Sunteți pe pagina 1din 53

Constantinescu Christian Tnas Mariana Grupa 244

1) irul lui Fibonacci S se scrie un program Prolog care sa afieze al n-lea numr din irul Fibonacci. Formula de recuren a irului lui Fibonacci este: xn = xn-1 + xn-2 , unde n>2, iar x1=1 i x2=1. Mulimea termenilor irului este {1, 1, 2, 3, 5, 8, 13, 21, ...}. fibonacci.pl
fib(1,1). fib(2,1). % x1=1

fib(N,F) :N>2, N1 is N-1, fib(N1,F1), N2 is N-2, fib(N2,F2), F is F1 + F2. % arborele atasat interogarii fib(6,F) este arborele urmator: % F(6) % / \ % / \ % / \ % F(5) F(4) % / \ / \ % / \ / \ % / \ / \ % F(4) F(3) F(3) F(2) % / \ /\ /\ % / \ / \ / \ % / \ / \ / \ % F(3) F(2) F(2) F(1) F(2) F(1) % /\ % / \ % / \ % F(2) F(1)

Interogaiile:
?- fib(8,F). F = 6 ? ; no ?- fib(5,F). F = 5 ? ; no

2) Problema turnurilor din hanoi Se dau n discuri i 3 tije A, B, C. Cele n discuri se afl pe tija A, un disc mai mic aflndu-se peste unul mai mare. Se cere s se mute toate discurile de pe A pe C folosind tija B, respectnd condiia ca un disc mai mic s se afle ntotdeauna peste unul mai mare. La final, pe tija B se vor afla toate discurile de pe A, n aceeai ordine. Notm cu xn numrul minim de mutri pentru a muta cele n discuri de pe A pe B folosind C. Se poate observa c dac xn este numrul de mutri pentru n discuri, atunci, folosind recursivitatea, se deduce c, pentru a muta n discuri se procedeaz astfel: folosind xn-1 mutri, se muta discurile de deasupra discului cel mai mare (sunt n-1) pe C (prin urmare se efectueaz xn-1 mutri), dup care discul rmas pe A care este cel mai mare, printr-o mutare se muta pe B, mutare urmat de xn-1 mutri pentru a trece n-1 discuri de pe C pe B folosind A. n concluzie xn = 2 * xn-1 + 1 (relaie de recuren), x1=1 hanoi.pl
mutare(0,_,_,_) :- ! . % cnd avem 0 discuri nu se face nimic % (oprirea procesului de cutare) mutare(N,A,B,C) :- N1 is N-1, mutare(N1,A,C,B), scrie(A,B), mutare(N1,C,B,A). scrie(X,Y) :- write([mutare,X,Y]), nl.

Interogaiile:
?- mutare(3,a,c,b). [mutare,a,c] [mutare,a,b] [mutare,c,b] [mutare,a,c] [mutare,b,a] [mutare,b,c] [mutare,a,c]

3) Relaii de familie familie.pl


parinte(pam,bob). parinte(tom,bob). parinte(tom,liz). parinte(bob,ann). parinte(bob,pat). parinte(pat,jim). feminin(pam). feminin(liz). feminin(ann). feminin(pat).

masculin(tom). masculin(bob). masculin(jim). sex(pam,feminin). sex(liz,feminin). sex(ann,feminin). sex(pat,feminin). sex(tom,masculin). sex(bob,masculin). sex(jim,masculin). diferit(X,Y) :- X\==Y. bunic(X) :- parinte(X,Z), parinte(Z,_), masculin(X). bunic(X,Y) :- parinte(X,Z), parinte(Z,Y), masculin(X). bunica(X) :- parinte(X,Z), parinte(Z,_), feminin(X). bunica(X,Y) :- parinte(X,Z), parinte(Z,Y), feminin(X). mama(X,Y) :- parinte(X,Y), feminin(X). tata(X,Y) :- parinte(X,Y), masculin(X). frate(X,Y) :- parinte(Z,X), parinte(Z,Y), masculin(X), diferit(X,Y). sora(X,Y) :- parinte(Z,X), parinte(Z,Y), feminin(X), diferit(X,Y). unchi(X,Y) :- parinte(Z,Y), (frate(Z,X); sora(Z,X)), masculin(X). matusa(X,Y) :- parinte(Z,Y), (frate(Z,X); sora(Z,X)), feminin(X). predecesor(X,Y) :- parinte(X,Y). predecesor(X,Y) :- parinte(X,Z), predecesor(Z,Y). rude(X,Y) :- predecesor(X,Y); predecesor(Y,X). rude(X,Y) :- predecesor(Z,X), predecesor(Z,Y). rude(X,Y) :- predecesor(X,Z), predecesor(Y,Z).

Interogaiile:
?- bunic(tom). yes ?- bunic(jim). no ?- bunic(X). X = tom ? ; X = tom ? ; X = bob ? ; no ?- bunica(pam). yes

?- bunica(ana). no ?- bunica(X). X = pam ? ; X = pam ? ; no ?- mama(pam,bob). yes ?- mama(tom,bob). no ?- mama(X,ann). no ?- mama(X,jim). X = pat ?- tata(tom,bob). yes ?- tata(tom,jim). no ?- tata(X,jim). no ?- tata(X,Y). X = tom, Y = bob ? ; X = tom, Y = liz ? ; X Y X Y no ?- frate(bob,liz). yes ?- frate(ann,pat). no ?- matusa(pam,liz). no ?- matusa(liz,pat). yes = = = = bob, ann ? ; bob, pat ? ;

?- predecesor(X,jim). X = pat ? ; X = pam ? ; X = tom ? ; X = bob ? ; no ?- rude(ann,liz). yes ?- rude(pam,tom). yes

4) Operaii cu liste S se scrie un program Prolog care s efectueze urmtoarele operaii cu liste: - cte elemente sunt n list; - dac X este element al listei; - tergerea unui element din list; - inserarea unui element n list; - concatenarea a 2 liste; - lipirea inversului unei liste la o alt list; - permutarea elementelor dintr-o list; - sublista unei liste; - ultimul element din list; - primul element din list. lista.pl
l([],0). % lista vida l([_|T],N) :- l(T,N1), N is 1+N1. % N=numarul de elemente ale listei member(X,[Y|T]) :- X==Y ; member(X,T). %X membru al listei care incepe %cu Y daca Y=X sau X este membru al listei T delete(X,[X|T],T). % terge elementul X din capul listei delete(X,[Y|T],[Y|T1]) :- delete(X,T,T1). % terge elementul X din % list insert(X,L,L1) :- delete(X,L1,L). % insereaz elementul X n lista L % concateneaz lista

concat([],L,L). concat([X|L1],L2,[X|L3]) :- concat(L1,L2,L3). % [X|L1] la lista L2

reverse([],L,L). reverse([X|L1],L2,L3) :- reverse(L1,[X|L2],L3). % concateneaz lista % [X|L1], inversat, la lista L2 reverse(A,R) :- reverse(A,[],R). perm([],[]). % spune dac lista A este inversul % listei R

perm([X|L],P) :- perm(L,L1),insert(X,L1,P). % afiseaz toate % permutrile elementelor din lista [X|L] subset([],_). subset([X|R],S) :- member(X,S), subset(R,S). % spune dac lista [X|R] % este sublist a listei S % spune dac X este ultimul element din lista [H] sau care e ultimul % element din list ultim(X,[H]) :- X=H. ultim(X,[_|T]) :- ultim(X,T). % spune dac X este primul element din lista [H|T] sau care e primul % element din list prim(X,[H|T]) :- X=H.

Interogaiile:
?- l([],0). yes ?- l([1,2,4],3). yes ?- l([1,2,4,5],3). no ?- l([1,2,4,5],X). X = 4 ?- member(4,[1,2,3,4,5,6]). yes ?- member(4,[1,2,3,5,6]). no ?- delete(1,[1,2,3,4,5,6],T). T = [2,3,4,5,6] ?- delete(3,[1,2,3,4,5,6],T). T = [1,2,4,5,6] ?- insert(7,[1,2,3,4,5,6],T). T = [7,1,2,3,4,5,6] ?- concat([],[1,2,3,4,5,6],L). L = [1,2,3,4,5,6] ?- concat([11,12,13],[1,2,3,4,5,6],L). L = [11,12,13,1,2,3,4,5,6] ?- reverse([],[1,2,3,4,5],L). L = [1,2,3,4,5] ?- reverse([7,8,9],[1,2,3,4,5],L). L = [9,8,7,1,2,3,4,5]

?- reverse([1,2,3,4],[5,6,7]). no ?- reverse([1,2,3,4],[4,3,2,1]). yes P P P P P P ?- perm([1,2,3],P). = [1,2,3] = [2,1,3] = [2,3,1] = [1,3,2] = [3,1,2] = [3,2,1]

?- subset([],_). yes ?- subset([],[1,2,3]). yes ?- subset([2,3],[1,2,3]). yes ?- subset([2,3,4],[1,2,3]). no ?- ultim(5,[5]). yes ?- ultim(X,[5]). X = 5 ?- ultim(5,[1,2,3,4,5]). yes ?- ultim(5,[1,2,3,4,5,6]). no ?- ultim(X,[1,2,3,4,5,6]). X = 6 ?- prim(X,[1,2,3,4]). X = 1 ?- prim(1,[1,2,3,4]). yes ?- prim(4,[1,2,3,4]). no

5) Minimul, maximul, c.m.m.d.c. a 2 numere i maximul si minimul elementelor unei liste operatii.pl
min(A,B,A) :- A<B, !. min(A,B,B). max(A,B,A) :- A>B,!. max(A,B,B). min([X],X). min([X|L],Z) :- min(L,Y), min(X,Y,Z). max([X],X). max([X|L],Z) :- max(L,Y), max(X,Y,Z). cmmdc(A,A,A). cmmdc(A,1,1). cmmdc(1,B,1). cmmdc(A,B,D) :- A>B, Y is A-B, cmmdc(Y,B,D). cmmdc(A,B,D) :- A<B, Y is B-A, cmmdc(A,Y,D).

Interogatiile:
?- min(3,7,X). X = 3 ?- min(19,7,X). X = 7 ?- max(5,20,X). X = 20 ?- max(21,20,X). X = 21 ?- min([3,6,9,2,90,45],X). X = 2 ?- max([3,6,9,2,90,45],X). X = 90 ?- cmmdc(70,45,X). X = 5

6) Problema celor 4 specialiti James, Tom, Bob i Jim tiu fiecare cte un singur si diferit limbaj de programare (HTML, C++, Java, respectiv Prolog) i sunt specializai n cte un domeniu diferit (matematic, fizic, chimie, biologie). Se tiu urmtoarele: a) cel care programeaz n Java e specializat n biologie;

b) c) d) e)

Tom nu tie nici Prolog, nici HTML i nu e specializat pe matematic; James nu tie nici Prolog, nici HTML i nu e specializat pe matematic; cel care e specializat n chimie nu programeaz n HTML; Bob e specialzat n fizic i nu programeaz n Prolog Ce limbaj de programare tie fiecare i n ce domeniu e specializat?

4specialisti.pl
nume(james). nume(tom). nume(bob). nume(jim). limbaj(html). limbaj(cpp). limbaj(java). limbaj(prolog). domeniu(matematica). domeniu(fizica). domeniu(chimie). domeniu(biologie). regula1(Y,Z):- Y=biologie, !, Z=java. regula1(_,_). regula2(X,Y,Z):- X=tom, !, Y\==matematica, Z\==prolog, Z\==html. regula2(_,_,_). regula3(X,Y,Z):- X=james, !, Y\==matematica, Z\==prolog, Z\==html. regula3(_,_,_). regula4(Y,Z):- Y=chimie, !, Z\==html. regula4(_,_). regula5(X,Y,Z):- X=bob, !, Y=fizica, Z\==prolog. regula5(_,_,_). rezolva(X,Y,Z):- nume(X), domeniu(Y), limbaj(Z), regula1(Y,Z), regula2(X,Y,Z), regula3(X,Y,Z), regula4(Y,Z), regula5(X,Y,Z). diferit(X1,X2,X3,X4):- X1\==X2, X1\==X3, X1\==X4, X2\==X3, X2\==X4, X3\==X4. solutie(Y1,Z1,Y2,Z2,Y3,Z3,Y4,Z4):- rezolva(james,Y1,Z1), rezolva(tom,Y2,Z2), rezolva(bob,Y3,Z3), rezolva(jim,Y4,Z4), diferit(Y1,Y2,Y3,Y4), diferit(Z1,Z2,Z3,Z4).

Interogaiile:
?- solutie(Y1,Z1,Y2,Z2,Y3,Z3,Y4,Z4).

Y1 Y2 Y3 Y4 Z1 Z2 Z3 Z4 Y1 Y2 Y3 Y4 Z1 Z2 Z3 Z4 no

= = = = = = = = = = = = = = = =

chimie, biologie, fizica, matematica, cpp, java, html, prolog ? ; biologie, chimie, fizica, matematica, java, cpp, html, prolog ? ;

7) Testul de inteligen al lui Einstein Prezumii: 1. Exist 5 case fiecare de alt culoare. 2. n fiecare cas locuiete o singur persoan, fiecare de alt nationalitate. 3. Fiecrui locatar i place o anumit butur, fumeaz o anumit marc de igri i deine un anumit animal de cas. 4. Nici una din cele 5 persoane nu bea aceeai butur, nu fumeaz aceeai marc de igri, i nu deine acelai animal de cas. Se dau urmtoarele: a) Britanicul locuiete n casa roie; b) Suedezul are un caine; c) Danezul bea ceai; d) Casa verde se afl n stnga casei albe; e) Locatarul casei verzi bea cafea; f) Persoana care fumeaz Pall Mall are o pasre; g) Locatarul casei din mijloc bea lapte; h) Locatarul casei galbene fumeaz Dunhill; i) Norvegianul locuiete n prima cas; j) Fumtorul de Marlboro locuiete lng cel care are o pisic; k) Locatarul care are un cal locuite lng cel care fumeaz Dunhill; l) Fumtorul de Winfield bea bere; m) Norvegianul locuiete lng casa albastr; n) Germanul fumeaz Rothmans; o) Fumtorul de Marlboro are un vecin care bea apa; Cine are acvariul cu peti?

einstein.pl
member(X,[X|_]). member(X,[Y|L]):- X==Y; member(X,L). next_to(X, Y, List) :- iright(X, Y, List). next_to(X, Y, List) :- iright(Y, X, List). iright(L, R, [L | [R | _]]). iright(L, R, [_ | Rest]) :- iright(L, R, Rest). einstein(Houses, Fish_Owner) :=(Houses, [ [casa, norvegian, _, _, _, _], _, [casa, _, _, _, lapte, _], _, _]), member([casa, britanic, _, _, _, rosu], Houses), member([casa, suedez, caine, _, _, _], Houses), member([casa, danez, _, _, ceai, _], Houses), iright([casa, _, _, _, _, verde], [casa, _, _, _, _, alb], Houses), member([casa, _, _, _, cafea, verde], Houses), member([casa, _, pasare, pallmall, _, _], Houses), member([casa, _, _, dunhill, _, galben], Houses), next_to([casa, _, _, dunhill, _, _], [casa, _, cal, _, _, _], Houses), member([casa, _, _, _, lapte, _], Houses), next_to([casa, _, _, marlboro, _, _], [casa, _, pisica, _, _, _], Houses), next_to([casa, _, _, marlboro, _, _], [casa, _, _, _, apa, _], Houses), member([casa, _, _, winfield, bere, _], Houses), member([casa, german, _, rothmans, _, _], Houses), next_to([casa, norvegian, _, _, _, _], [casa, _, _, _, _, albastru], Houses), member([casa, Fish_Owner, peste, _, _, _], Houses).

Interogaiile:
?- einstein(Houses,Fish_Owner). Houses = [[casa,norvegian,pisica,dunhill,apa,galben], [casa,danez,cal,marlboro,ceai,albastru], [casa,britanic,pasare,pallmall,lapte,rosu], [casa,german,peste,rothmans,cafea,verde], [casa,suedez,caine,winfield,bere,alb]], Fish_Owner = german

8) Derivare simbolic Derivarea expresiilor aritmetice (David H. D. Warren) derivare_simbolica.pl


% prioritatea operatorului de putere

:- op(300,xfy,**). % reguli de derivare d(X,X,D) :- atomic(X), !, D=1. d(C,X,D) :- atomic(C), !, D=0. d(U+V,X,DU+DV) :- d(U,X,DU), d(V,X,DV). d(U-V,X,DU-DV) :- d(U,X,DU), d(V,X,DV). d(U*V,X,DU*V+U*DV) :- d(U,X,DU), d(V,X,DV). d(U**N,X,N*U**N1*DU) :- integer(N), N1 is N-1, d(U,X,DU). d(-U,X,-DU) :- d(U,X,DU). % end

Interogaiile:
?- d(2*x,x,D). D = 0*x+2*1 ?- d(x**10,x,D). D = 10*x**9*1 ?- d(x**5+x**7,x,D). D = 5*x**4*1+7*x**6*1 ?- d(-x**2-x**5+x**7,x,D). D = -(2*x**1*1)-5*x**4*1+7*x**6*1

1. Testul lui Einstein


membru(X,[X | _]). membru(X,[_ | T]):-membru(X,T). dreapta(X,Y,[ X , Y | _ ]). dreapta(X,Y,[ _ | T ]):-dreapta(X,Y,T). stanga(X,Y,Lista):-dreapta(Y,X,Lista). langa(X,Y,Lista):-dreapta(X,Y,Lista);stanga(X,Y,Lista). einstein(X):-reguli(Case),membru([_,X,_,_,pesti],Case). reguli(Case):Case=[_,_,_,_,_],regulaa(Case),regulab(Case),regulac(Case),regulad(Case),regulae(Case) ,regulaf(Case),regulag(Case),regulah(Case),regulai(Case),regulaj(Case),regulak(Case),re gulal(Case),regulam(Case),regulan(Case),regulao(Case). regulaa(Case):-membru([rosu,britanic,_,_,_],Case). regulab(Case):-membru([_,suedez,_,_,caine],Case). regulac(Case):-membru([_,danez,ceai,_,_],Case). regulad(Case):-stanga([verde,_,_,_,_],[alb,_,_,_,_],Case). regulae(Case):-membru([verde,_,cafea,_,_],Case). regulaf(Case):-membru([_,_,_,pallmall,pasare],Case). regulag(Case):-Case=[_,_,[_,_,lapte,_,_],_,_].

regulah(Case):-membru([galben,_,_,dunhill,_],Case). regulai(Case):-Case=[[_,norvegian,_,_,_],_,_,_,_]. regulaj(Case):-langa([_,_,_,malboro,_],[_,_,_,_,pisica],Case). regulak(Case):-langa([_,_,_,_,cal],[_,_,_,dunhill,_],Case). regulal(Case):-membru([_,_,bere,winfield,_],Case). regulam(Case):-langa([_,norvegian,_,_,_],[albastru,_,_,_,_],Case). regulan(Case):-membru([_,german,_,rothmans,_],Case). regulao(Case):-langa([_,_,_,malboro,_],[_,_,apa,_,_],Case). Interogare:

2. % Problema Turnurilor din Hanoi


% Scopul acestui "puzzle" este de a muta n discuti de pe bara din stanga pe bara din dreapta folosind bara din centru ca pe una auxiliara. % Important este ca un disc mai mare nu poate fi asezat pe un disc mai mic si la un moment dat poate fi mutat numai unul. muta(1,X,Y,_) :- write('Muta discut din '),write(X),write(' in '),write(Y),nl. muta(N,X,Y,Z) :- N>1,M is N-1,muta(M,X,Z,Y),muta(1,X,Y,Z),muta(M,Z,Y,X). Interogari :

3. % Merge sort ( foloseste divide et impera)


mergesort([],[]). mergesort([A],[A]). mergesort([A,B|R],S) :- split([A,B|R],L1,L2), mergesort(L1,S1),mergesort(L2,S2),merge(S1,S2,S). split([],[],[]). split([A],[A],[]). split([A,B|R],[A|Ra],[B|Rb]) :- split(R,Ra,Rb).

merge(A,[],A). merge([],B,B). merge([A|Ra],[B|Rb],[A|M]) :- A=< B, merge(Ra,[B|Rb],M). merge([A|Ra],[B|Rb],[B|M]) :- A >B, merge([A|Ra],Rb,M). Interogari :

4. % Quicksort (Se gaseste un pivot; tot ce e mai mic se trece in stanga; tot ce e mai mare se trece in dr) quicksort([],[]). quicksort([H|T],Sorted) :- pivoting(H,T,L1,L2), % pivotul H, lista T se imparte in L1(=<H) si L2(>H) quicksort(L1,Sorted1), quicksort(L2,Sorted2), append(Sorted1,[H|Sorted2],Sorted). pivoting(H,[],[],[]). pivoting(H,[X|T],[X|L],G) :- X=<H,pivoting(H,T,L,G). pivoting(H,[X|T],L,[X|G]) :- X>H,pivoting(H,T,L,G). append([],A,A). append([X|L1],L2,[X|L]) :- append(L1,L2,L). Interogari:

5. % Sudoku
% Regula de joc: Casuta de 9*9 , impartita in 9 casute de 3*3. In fiecare casuta, pe linii si pe coloane % sunt cifre distincte de la 1 la 9.

:- use_module(library(clpfd)). :- use_module(library(lists)).

test1 :L=[ [_,6,_,1,_,4,_,5,_], [_,_,8,3,_,5,6,_,_], [2,_,_,_,_,_,_,_,1], [8,_,_,4,_,7,_,_,6], [_,_,6,_,_,_,3,_,_], [7,_,_,9,_,1,_,_,4], [5,_,_,_,_,_,_,_,2], [_,_,7,2,_,6,9,_,_], [_,4,_,5,_,8,_,7,_]], sudoku(L), pretty_print(L). test2 :L=[ [_,_,4 ,_,_,3, _,7,_],

[_,8,_ ,_,7,_, _,_,_], [_,7,_ ,_,_,8, 2,_,5], [4,_,_ ,_,_,_, 3,1,_], [9,_,_ ,_,_,_, _,_,8], [_,1,5 ,_,_,_, _,_,4], [1,_,6 ,9,_,_, _,3,_], [_,_,_ ,_,2,_, _,6,_], [_,2,_ ,4,_,_, 5,_,_]], sudoku(L), pretty_print(L).

test3 :L= [ [_,4,3,_,8,_,2,5,_], [6,_,_,_,_,_,_,_,_], [_,_,_,_,_,1,_,9,4], [9,_,_,_,_,4,_,7,_], [_,_,_,6,_,8,_,_,_], [_,1,_,2,_,_,_,_,3], [8,2,_,5,_,_,_,_,_], [_,_,_,_,_,_,_,_,5], [_,3,4,_,9,_,7,1,_] ], sudoku(L), pretty_print(L). test4 :L= [ [8,_,3,_,2,9,7,1,6], [_,_,6,_,1,8,5,_,4], [_,_,_,_,6,_,_,_,8], [_,_,5,_,4,6,_,8,_], [7,_,9,_,3,5,6,4,2], [_,6,_,_,9,_,1,_,5], [6,_,_,_,7,_,_,5,1], [_,_,1,6,5,_,8,_,_], [5,_,_,9,8,1,4,6,3] ], sudoku(L), pretty_print(L).

test5 :L=[ [_,_,_,1,5,_,_,7,_], [1,_,6,_,_,_,8,2,_], [3,_,_,8,6,_,_,4,_], [9,_,_,4,_,_,5,6,7], [_,_,4,7,_,8,3,_,_], [7,3,2,_,_,6,_,_,4], [_,4,_,_,8,1,_,_,9], [_,1,7,_,_,_,2,_,8], [_,5,_,_,3,7,_,_,_] ], sudoku(L), pretty_print(L). %O lista de 9*9 sudoku(L) :flatten(L,AllVars), % flatten(Xs,Ys) is true if Ys is a list of the elements of Xs domain(AllVars,1,9), [R1,R2,R3,R4,R5,R6,R7,R8,R9] = L, %fiecare linie e diferita all_different(R1), all_different(R2), all_different(R3), all_different(R4), all_different(R5), all_different(R6), all_different(R7), all_different(R8), all_different(R9), transpose(L,TL), % traspusa unei matrice %fiecare coloana e diferita [C1,C2,C3,C4,C5,C6,C7,C8,C9] = TL, all_different(C1), all_different(C2), all_different(C3), all_different(C4), all_different(C5), all_different(C6), all_different(C7), all_different(C8), all_different(C9), %fiecare casuta de 3*3 trebuie sa aibe elemente distincte [X11,X12,X13,X14,X15,X16,X17,X18,X19] = R1, [X21,X22,X23,X24,X25,X26,X27,X28,X29] = R2, [X31,X32,X33,X34,X35,X36,X37,X38,X39] = R3, [X41,X42,X43,X44,X45,X46,X47,X48,X49] = R4, [X51,X52,X53,X54,X55,X56,X57,X58,X59] = R5, [X61,X62,X63,X64,X65,X66,X67,X68,X69] = R6, [X71,X72,X73,X74,X75,X76,X77,X78,X79] = R7, [X81,X82,X83,X84,X85,X86,X87,X88,X89] = R8, [X91,X92,X93,X94,X95,X96,X97,X98,X99] = R9, all_different([X11,X12,X13,X21,X22,X23,X31,X32,X33]), all_different([X41,X42,X43,X51,X52,X53,X61,X62,X63]), all_different([X71,X72,X73,X81,X82,X83,X91,X92,X93]),

all_different([X14,X15,X16,X24,X25,X26,X34,X35,X36]), all_different([X44,X45,X46,X54,X55,X56,X64,X65,X66]), all_different([X74,X75,X76,X84,X85,X86,X94,X95,X96]), all_different([X17,X18,X19,X27,X28,X29,X37,X38,X39]), all_different([X47,X48,X49,X57,X58,X59,X67,X68,X69]), all_different([X77,X78,X79,X87,X88,X89,X97,X98,X99]),

labeling([ffc],AllVars).

flatten([],[]). flatten([H|T],Vars) :flatten(T,TVars), append(H,TVars,Vars). % transpune o lista in liste transpose([Word], Cs) :- !, R = Word, list2columns(R, Cs). transpose([Word|Words], Cs) :- !, transpose(Words, Cs0), R=Word, put_columns(R, Cs0, Cs).

% uneste H cu TVars si iese Vars

list2columns([], []). list2columns([X|Xs], [[X]|Zs]) :- list2columns(Xs, Zs). put_columns([], Cs, Cs). put_columns([X|Xs], [C|Cs0], [[X|C]|Cs]) :- put_columns(Xs, Cs0, Cs).

pretty_print([]). pretty_print([H|T]) :write(H),nl, pretty_print(T). Interogari:

6. Problema damelor
solution(Board) :permutation([1,2,3,4,5,6,7,8], Board), safe(Board). permutation([], []). permutation([A|M], N) :permutation(M, N1), insert(A, N1, N). insert(A, L, [A|L]).

insert(A, [B|L], [B|L1]) :- insert(A, L, L1). safe([Q]). safe([Q|List]) :- nodiag(Q, List, 1), safe(List). nodiag(Q, [], Dist). nodiag(Q1, [Q2|List], Dist) :noattack(Q1, Q2, Dist), NewDist is Dist + 1, nodiag(Q1, List, NewDist). noattack(Q1, Q2, Dist) :Q2 - Q1 =\= Dist, Q1 - Q2 =\= Dist. Interogari :

7. % Parcurgerea in adancime si cautarea unui element in adancime s(a,b). s(a,c). s(b,d). s(d,h). s(b,e). s(e,i). s(e,j). s(c,f). s(c,g). s(f,k). s(g,l). s(l,m). s(l,n). 2

scop(f). scop(j). scop(m). df(Nod) :- write(Nod), write(' '), s(Nod,X), df(X). rezolva(N,Sol) :-depthfirst([],N,Sol). depthfirst(Drum,Nod,[Nod|Drum]) :- scop(Nod). depthfirst(Drum,Nod,Sol) :- s(Nod,Nod1), \+(membru(Nod1,Drum)),depthfirst([Nod|Drum],Nod1,Sol). membru(H,[H|T]). membru(X,[H|T]) :- membru(X,T). Interogari :

8. % Testul lui Einstein simplificat


% James, Tom si Jim cunosc fiecare cate un limbaj de programare(HTML,Cpp,Java,Prolog) si sunt specializati in cate un % domeniu(mate,fizica,chimie,biologie). % Se stiu urmatoarele: % 1.Cel care stie Java e specializat in biologie. % 2.Tom nu stie nici Prolog nici HTML, nici matematica. % 3.James nu stie nici Prolog nici HTML, nici matematica. % 4.Cel specializat in chimie nu stie HTML.

% 5.Bob e specializat in fizica si nu stie Prolog. % Ce limbaj de programare stie fiecare si in ce e specializat ? % Fapte: name(james). name(tom). name(bob). name(jim). language(html). language(cpp). language(java). language(prolog). field(mate). field(fizica). field(chimie). field(biologie). % Reguli : rule1(Y,Z) :- Y=biologie,!,Z=java. rule1(_,_). rule2(X,Y,Z) :- X=tom,!,Y\==mate,Z\==prolog,Z\==html. rule2(_,_,_). rule3(X,Y,Z) :- X=james,!,Y\==mate,Z\==prolog,Z\==html. rule3(_,_,_). rule4(Y,Z) :- Y=chimie,!,Z\==html. rule4(_,_). rule5(X,Y,Z) :- X=bob,!,Y=fizica,Z\==prolog. rule5(_,_,_). solve(X,Y,Z) :name(X),field(Y),language(Z),rule1(Y,Z),rule2(X,Y,Z),rule3(X,Y,Z),rule4(Y,Z),rule5(X, Y,Z). notequal(X1,X2,X3,X4) :- X1\==X2,X1\==X3,X1\==X4,X2\==X3,X2\==X4,X3\==X4. solution(Y1,Z1,Y2,Z2,Y3,Z3,Y4,Z4) :- solve(james,Y1,Z1), solve(tom,Y2,Z2), solve(bob,Y3,Z3), solve(jim,Y4,Z4), notequal(Y1,Y2,Y3,Y4), notequal(Z1,Z2,Z3,Z4). Interogari :

9. % Cautare intr-un arbore binar


arb(2,arb(1,n,n),arb(6,arb(4,arb(3,n,n),arb(5,n,n)),arb(7,n,n))). caut(X) :- c(X,arb(2,arb(1,n,n),arb(6,arb(4,arb(3,n,n),arb(5,n,n)),arb(7,n,n)))). c(X,arb(T,A,B)) :- X==T,write('gasit'). c(X,arb(T,A,B)) :- X<T,A\==n,c(X,A). c(X,arb(T,A,B)) :- X>T,B\==n,c(X,B). Interogari :

Liste
/* Op. liste */ lung([], 0). lung([_ | T], N):- lung(T, N1), N is N1 + 1. mem(X, [X | _]). mem(X, [_ | T]):- mem(X, T).

conc([], L, L). conc([X | L1], L2, [X | L3]):- conc(L1, L2, L3). ultim(X, [H]):- X = H. ultim(X, [_ | T]):- ultim(X, T). del(X, [X | T], T). del(X, [Y | T], [Y | T1]):- del(X, T, T1). ins(X, L, L1):- del(X, L1, L). /* Permutare */ perm([], []). perm([X | L], P):- perm(L, L1), ins(X, L1, P). | ?- perm([1, 2, 3], X). X = [1,2,3] ? ; X = [2,1,3] ? ; X = [2,3,1] ? ; X = [1,3,2] ? ; X = [3,1,2] ? ; X = [3,2,1] ? ; no /* Submultimi */ subset([], []). subset([X | Xs], [X | Ys]):- subset(Xs, Ys). subset([_ | Xs], Ys):- subset(Xs, Ys). | ?- subset([1, 2, 3], X). X = [1,2,3] ? ; X = [1,2] ? ; X = [1,3] ? ; X = [1] ? ; X = [2,3] ? ; X = [2] ? ;

X = [3] ? ; X = [] ? ; no

Cmmdc
cmmdc(X, X, X). cmmdc(X, Y, D):- (Y > X), Y1 is Y - X, cmmdc(X, Y1, D). cmmdc(X, Y, D):- (X > Y), X1 is X - Y, cmmdc(X1, Y, D). | ?- cmmdc(12, 40, X). X = 4 ? yes | ?- cmmdc(225, 750, X). X = 75 ? yes

Testul lui Einstein


next_to(X, Y, List) :- iright(X, Y, List). next_to(X, Y, List) :- iright(Y, X, List). iright(L, R, [L | [R | _]]). iright(L, R, [_ | Rest]) :- iright(L, R, Rest). member(X, [X | _]). member(X, [_ | T]) :- member(X, T). einstein(Houses, Fish_Owner) :=(Houses, [[house, norwegian, _, _, _, _], _, [house, _, _, _, milk, _], _, _]), member([house, brit, _, _, _, red], Houses), member([house, swede, dog, _, _, _], Houses), member([house, dane, _, _, tea, _], Houses), iright([house, _, _, _, _, green], [house, _, _, _, _, white], Houses), member([house, _, _, _, coffee, green], Houses), member([house, _, bird, pallmall, _, _], Houses), member([house, _, _, dunhill, _, yellow], Houses), next_to([house, _, _, dunhill, _, _], [house, _, horse, _, _, _], Houses), member([house, _, _, _, milk, _], Houses), next_to([house, _, _, marlboro, _, _], [house, _, cat, _, _, _], Houses),

next_to([house, _, _, marlboro, _, _], [house, _, _, _, water, _], Houses), member([house, _, _, winfield, beer, _], Houses), member([house, german, _, rothmans, _, _], Houses), next_to([house, norwegian, _, _, _, _], [house, _, _, _, _, blue], Houses), member([house, Fish_Owner, fish, _, _, _], Houses). | ?- einstein(Houses, Fish_Owner). Houses = [[house,norwegian,cat,dunhill,water,yellow],[house,dane,horse,mar lboro,tea,blue],[house,brit,bird,pallmall,milk,red],[house,german ,fish,rothmans,coffee,green],[house,swede,dog,winfield,beer,white ]], Fish_Owner = german ? yes | ?-

Derivare
d(X,X,1) :- !. /* d x dx = 1 */ d(C,_,0) :- atomic(C). /* d c dx = 0 */ d(-U,X,-A) :- d(U,X,A). /* d -u dx = - d u dx */ d(U+V,X,A+B) :- d(U,X,A), d(V,X,B). /* d u+v dx = d u dx + d v dx */ d(U-V,X,A-B) :- d(U,X,A), d(V,X,B). /* d u-v dx = d u dx - d v dx */ d(C*U,X,C*A) :- atomic(C), C \== X, d(U,X,A), !. /* d c*u dx = c*d u dx */ d(U*V,X,B*U+A*V) :- d(U,X,A), d(V,X,B). /* d u*v dx = u*d v dx + v*d u dx */ d(U/V,X,A) :- d(U*V^(-1),X,A). /* d u/v dx = d (u*v)^-1 dx */ d(U^C,X,C*U^(C-1)*W) :- atomic(C), C \== X, d(U,X,W). /* d u^c dx = c*u^(c-1)*d u dx */

d(log(U),X,A*U^(-1)) :- d(U,X,A). /* d ln(u) dx = u^-1 * d u dx */


| ?- d(x*x, x, X). X = 1*x+1*x ? | ?- d(x*x*x + x*x + x + 1, x, X). X = 1*(x*x)+(1*x+1*x)*x+(1*x+1*x)+1+0 ?

Grigore Mircea Probleme Inteligenta Artificiala


Problema 1 - Testul de inteligenta al lui Einstein
% structura folosita: casa(culoare, nationalitate, bautura, tigari, animal) test(Case) :% Norvegianul locuieste in prima casa. % Locatarul casei din mijloc bea lapte. Case = [casa(_, norvegian, _, _, _), _, casa(_, _, lapte, _, _), _, _], % Britanicul locuieste in casa rosie. membru(casa(rosu, britanic, _, _, _), Case), % Suedezul are un caine. membru(casa(_, suedez, _, _, caine), Case), % Danezul bea ceai. membru(casa(_, danez, ceai, _, _), Case), % Casa verde se afla in stanga casei albe. laDreapta(casa(verde, _, _, _, _), casa(alb, _, _, _, _), Case), % Locatarul casei verzi bea cafea. membru(casa(verde, _, cafea, _, _), Case), % Persoana care fumeaza PallMall are o pasare. membru(casa(_, _, _, pallmall, pasare), Case), % Locatarul casei galbene fumeaza Dunhill. membru(casa(galben, _, _, dunhill, _), Case), % Fumatorul de Marlboro locuieste langa cel care are o pisica. alaturi(casa(_, _, _, marlboro, _), casa(_, _, _, _, pisica), Case), % Locatarul care are un cal locuieste langa cel care fumeaza Dunhill. alaturi(casa(_, _, _, _, cal), casa(_, _, _, dunhill, _), Case), % Fumatorul de Winfield bea bere. membru(casa(_, _, bere, winfield, _), Case), % Norvegianul locuieste langa casa albastra. alaturi(casa(_, norvegian, _, _, _), casa(albastru, _, _, _, _), Case), % Germanul fumeaza Rothmans. membru(casa(_, german, _, rothmans, _), Case), % Fumatorul de Marlboro are un vecin care bea apa.

alaturi(casa(_, _, _, marlboro, _), casa(_, _, apa, _, _), Case), % Cineva detine un acvariu cu pesti. membru(casa(_, _, _, _, pesti), Case). membru(X, [X | _]). membru(X, [_ | T]) :membru(X, T). laDreapta(X, Y, [X, Y | T]). laDreapta(X, Y, [_ | T]) :laDreapta(X, Y, T). alaturi(X, Y, L) :laDreapta(X, Y, L); laDreapta(Y, X, L). raspunsPesti(Locatar) :test(Case), membru(casa(_, Locatar, _, _, pesti), Case).

Interogari : | ?- raspunsPesti(X). X = german ?

Problema 2 Rezolvarea unui joc SUDOKU 9x9


:- use_module(library(clpfd)). :- use_module(library(lists)). test1 :L=[ [_,_,_,_,6,1,_,_,5], [8,_,_,_,5,_,_,_,_], [_,_,_,_,_,_,8,4,7], [_,5,_,_,_,_,9,_,_], [6,_,_,9,_,4,_,_,8], [_,_,3,_,_,_,_,1,_], [7,9,1,_,_,_,_,_,_], [_,_,_,_,8,_,_,_,2], [5,_,_,7,3,_,_,_,_]], sudoku(L), pretty_print(L). %Fiendish puzzel April 21,2005 Times London test2 :L=[ [_,_,4 ,_,_,3, _,7,_], [_,8,_ ,_,7,_, _,_,_], [_,7,_ ,_,_,8, 2,_,5], [4,_,_ ,_,_,_, 3,1,_], [9,_,_ ,_,_,_, _,_,8], [_,1,5 ,_,_,_, _,_,4],

[1,_,6 ,9,_,_, _,3,_], [_,_,_ ,_,2,_, _,6,_], [_,2,_ ,4,_,_, 5,_,_]], sudoku(L), pretty_print(L). test3 :%This is supposed to be hard. L= [ [_,4,3,_,8,_,2,5,_], [6,_,_,_,_,_,_,_,_], [_,_,_,_,_,1,_,9,4], [9,_,_,_,_,4,_,7,_], [_,_,_,6,_,8,_,_,_], [_,1,_,2,_,_,_,_,3], [8,2,_,5,_,_,_,_,_], [_,_,_,_,_,_,_,_,5], [_,3,4,_,9,_,7,1,_] ], sudoku(L), pretty_print(L). test4 :%Diaboloical puzzel 104 Sunday Torygraph. L= [ [8,_,3,_,2,9,7,1,6], [_,_,6,_,1,8,5,_,4], [_,_,_,_,6,_,_,_,8], [_,_,5,_,4,6,_,8,_], [7,_,9,_,3,5,6,4,2], [_,6,_,_,9,_,1,_,5], [6,_,_,_,7,_,_,5,1], [_,_,1,6,5,_,8,_,_], [5,_,_,9,8,1,4,6,3] ], sudoku(L), pretty_print(L). test5 :%An easy sudoku from the web. L=[ [_,_,_,1,5,_,_,7,_], [1,_,6,_,_,_,8,2,_], [3,_,_,8,6,_,_,4,_], [9,_,_,4,_,_,5,6,7], [_,_,4,7,_,8,3,_,_], [7,3,2,_,_,6,_,_,4], [_,4,_,_,8,1,_,_,9], [_,1,7,_,_,_,2,_,8],

[_,5,_,_,3,7,_,_,_] ], sudoku(L), pretty_print(L). %Expects a list of lists 9 by 9 grid. sudoku(L) :flatten(L,AllVars), domain(AllVars,1,9), [R1,R2,R3,R4,R5,R6,R7,R8,R9] = L, %Each row is different. all_different(R1), all_different(R2), all_different(R3), all_different(R4), all_different(R5), all_different(R6), all_different(R7), all_different(R8), all_different(R9), transpose(L,TL), %Each column is different. [C1,C2,C3,C4,C5,C6,C7,C8,C9] = TL, all_different(C1), all_different(C2), all_different(C3), all_different(C4), all_different(C5), all_different(C6), all_different(C7), all_different(C8), all_different(C9), %Need to put the code in to do each 3x3 square all different. %There is a much more elegant way of coding this. But for %illustrative purposes it is fine. [X11,X12,X13,X14,X15,X16,X17,X18,X19] = R1, [X21,X22,X23,X24,X25,X26,X27,X28,X29] = R2, [X31,X32,X33,X34,X35,X36,X37,X38,X39] = R3, [X41,X42,X43,X44,X45,X46,X47,X48,X49] = R4, [X51,X52,X53,X54,X55,X56,X57,X58,X59] = R5, [X61,X62,X63,X64,X65,X66,X67,X68,X69] = R6, [X71,X72,X73,X74,X75,X76,X77,X78,X79] = R7, [X81,X82,X83,X84,X85,X86,X87,X88,X89] = R8, [X91,X92,X93,X94,X95,X96,X97,X98,X99] = R9, all_different([X11,X12,X13,X21,X22,X23,X31,X32,X33]), all_different([X41,X42,X43,X51,X52,X53,X61,X62,X63]), all_different([X71,X72,X73,X81,X82,X83,X91,X92,X93]), all_different([X14,X15,X16,X24,X25,X26,X34,X35,X36]), all_different([X44,X45,X46,X54,X55,X56,X64,X65,X66]), all_different([X74,X75,X76,X84,X85,X86,X94,X95,X96]), all_different([X17,X18,X19,X27,X28,X29,X37,X38,X39]), all_different([X47,X48,X49,X57,X58,X59,X67,X68,X69]), all_different([X77,X78,X79,X87,X88,X89,X97,X98,X99]), labeling([ffc],AllVars). flatten([],[]). flatten([H|T],Vars) :-

flatten(T,TVars), append(H,TVars,Vars). /* Transpose a list of lists. */ /* This is modfied from code by Naoyuki Tamura (tamura@kobe-u.ac.jp) *. /* Used without permisson. */ transpose([Word], Cs) :- !, /* reverse(Word, R), */ R = Word, list2columns(R, Cs). transpose([Word|Words], Cs) :- !, transpose(Words, Cs0), /* reverse(Word, R), */ R=Word, put_columns(R, Cs0, Cs). list2columns([], []). list2columns([X|Xs], [[X]|Zs]) :- list2columns(Xs, Zs). put_columns([], Cs, Cs). put_columns([X|Xs], [C|Cs0], [[X|C]|Cs]) :- put_columns(Xs, Cs0, Cs). /* Pretty Print L */ pretty_print([]). pretty_print([H|T]) :write(H),nl, pretty_print(T). Interogari : Pentru a rezolva un Sudoku rulati testele implementate deja in cod . (Ex : test1. , test2. , -> -> test5. ) | ?- test1. [4,7,9,8,6,1,3,2,5] [8,3,2,4,5,7,1,6,9] [1,6,5,2,9,3,8,4,7] [2,5,4,3,1,8,9,7,6] [6,1,7,9,2,4,5,3,8] [9,8,3,6,7,5,2,1,4] [7,9,1,5,4,2,6,8,3] [3,4,6,1,8,9,7,5,2] [5,2,8,7,3,6,4,9,1] | ?- test2. [2,5,4,1,9,3,8,7,6] [6,8,9,5,7,2,1,4,3] [3,7,1,6,4,8,2,9,5] [4,6,2,8,5,9,3,1,7] [9,3,7,2,1,4,6,5,8] [8,1,5,7,3,6,9,2,4] [1,4,6,9,8,5,7,3,2]

[5,9,8,3,2,7,4,6,1] [7,2,3,4,6,1,5,8,9]

Problema 3 Problema damelor


/* Afalti cum se pot aseza damele pe o tabla de sah astfel incat acestea san nu se atace printr-o singura mutare. */ solution([]). solution([X/Y | Others]) :solution(Others), member(Y, [1, 2, 3, 4, 5, 6, 7, 8]), noattack(X/Y, Others). noattack(_, []). noattack(X/Y, [X1/Y1 | Others]) :Y =\= Y1, Y1 - Y =\= X1 - X, Y1 - Y =\= X - X1, noattack(X/Y, Others). member(X, [X | L]). member(X, [Y | L]) :member(X, L). template([1/Y1, 2/Y2, 3/Y3, 4/Y4, 5/Y5, 6/Y6, 7/Y7, 8/Y8]).

Interogari : |-? template(S), solution(S) . S = [1/4,2/2,3/7,4/3,5/6,6/8,7/5,8/1] ?

Problema 4 Monkey and Banana (Maimuta si banana)


/* O maimutza se afla intr-o camera langa usa. In mijlocul camerei se afla o banana legata de tavan. Maimuta este flamanda si vrea banana dar nu poate ajunge la ea. La fereastra este o cutie pe care maimutza o poate folosi. Maimuta poate face urmatoarele lucruri : sa se plimbe pe podea, sa se urce pe cutie, sa impinge cutia prin camera (daca se afla langa cutie) si sa ia banana daca se afla pe cutie si sub banana. Poate maimuta sa ia banana? */ move(state(middle, onbox, middle, hasnot), grasp, state(middle, onbox, middle, has)).

move(state(P, onfloor, P, H), climb, state(P, onbox, P, H)). move(state(P1, onfloor, P1, H), push(P1, P2), state(P2, onfloor, P2, H)). move(state(P1, onfloor, B, H), walk(P1, P2), state(P2, onfloor, B, H)). canget(state(_, _, _, has)). canget(State1) :move(State1, Move, State2), canget(State2). Interogari : |-? canget(state(middle,onbox,middle,hasnot)). Yes.

Problema 5 Automat finit


final(s3). %definim starea finala trans(s1, a, s1). %definim starile trans(s1, a, s2). trans(s1, b, s1). trans(s2, b, s3). trans(s3, b, s4). silent(s2, s4). %definim starile prin care se poate ajunge direct silent(s3, s1). accepts(S, []) :final(S). accepts(S, [X | Rest]) :trans(S, X, S1), accepts(S1, Rest). accepts(S, String) :silent(S, S1), accepts(S1, String). Interogari :

|?- accept(s1,[a,a,b]). yes

Problema 6 Relatii de familie


parent( pam, bob). parent( tom, bob). parent( tom, liz). parent( bob, ann). parent( bob, pat). parent( pat, jim). female( pam). male( tom). male( bob). female( liz). female( ann). female( pat). male( jim). offspring( Y, X) :parent( X, Y). mother( X, Y) :parent( X, Y), female( X). grandparent(X, Z) :parent( X, Y), parent( Y, Z). sister( X, Y) :parent( Z, X), and parent( Z, Y), female( X), different( X, Y ). predecessor( X, Z ) :parent( X, Z ). predecessor( X, Z) :parent( X, Y), predecessor( Y, Z). relatives( X, Y) :predecessor( X, Y). % Pam is a parent of Bob

% Pam is female % Tom is male

% Y is an offspring of X if % X is a parent of Y % X is the mother of Y if % X is a parent of Y and % X is female % X is a grandparent of Z if % X is a parent of Y and % Y is a parent of Z % X is a sister of Y if % X and Y have the same parent

% X is female and % X and Y are different % Rule prl: X is a predecessor of Z % Rule pr2: X is a predecessor of Z

relatives( X, Y) :predecessorY( , X). relatives( X, Y) :Predecessor predecessor( Z, X), predecessor( X, Y). relatives( X, Y) :successor predecessorX( X, Z), predecessor( Y,Z ). % X and Y have a common

% X and Y have a common

Problema 7 Liste
% LISTE - Reprezentare % -------------------% Lungimea % Fapte l([],0) . % Reguli l([_ | T ] , N ) :- l(T , N1) , N is 1 + N1 . % Membru member(X,[ X | T ]). member(X,[ H | T ]) :- member(X,T) . membru(X,[ X | _ ]). membru(X,[ _ | T ]) :- membru(X,T) . % Concatenare % predicat conc(L1,L2,L3) : L3 = L1L2 conc([ ],L,L). conc([ X | L1 ],L2,[ X | L3 ]) :- conc(L1,L2,L3) . % Ultimul element % predicat ultim(X,L) ultim(X,[ H ]) :- X=H. ultim(X,[ _ | T ]) :- ultim(X,T) . % Inserare

insert(X,L,L1) :- del(X,L1,L) . % Stergere del del(X,[ X | T ], T). del(X,[ Y | T ], [ Y | T1 ]) :- del(X,T,T1) . % Permutarea elementelor unei liste. perm([],[]) . perm([ X | L ],P) :- perm(L,L1), insert(X,L1,P) . perm1([],[]) . perm1(L , [ X | P ]) :- del(X,L,L1), perm(L1,P) . subset([],[]). subset([X|Xs], [X|Ys]) :- subset(Xs, Ys). subset([_|Xs], Ys) :- subset(Xs, Ys).

Interogari : perm( [ 1, 2, 3, 4, 5 ], P ) . P = [1,2,3,4,5] ? ; P = [2,1,3,4,5] ? ; P = [2,3,1,4,5] ? ; P = [2,3,4,1,5] ? ; P = [2,3,4,5,1] ? ; P = [1,3,2,4,5] ? ; P = [3,1,2,4,5] ? ;

Problema 8
% P15 (**): Dubleaza elementele unei liste de un numar de ori % dupli(L1,N,L2) :- L2 este obtinut din L1 prin duplicarea tuturor elementelor de N ori. % (list,integer,list) (?,+,?) dupli(L1,N,L2) :- dupli(L1,N,L2,N). % dupli(L1,N,L2,K) :- L2 este obtinutn din L1 prin duplicarea primului element % de K ori, iar restul elementelor duplicandu-le de N.

(list,integer,list,integer) (?,+,?,+)

dupli([],_,[],_). dupli([_|Xs],N,Ys,0) :- dupli(Xs,N,Ys,N). dupli([X|Xs],N,[X|Ys],K) :- K > 0, K1 is K - 1, dupli([X|Xs],N,Ys,K1).

Interogari : Dupli ( [ x, y, z ], 4, L ). L = [x,x,x,x,y,y,y,y,z,z|...] ? ; Dupli ( [ x, y, z, t ], 6 ,L ). L = [x,x,x,x,x,x,y,y,y,y|...] ?

Problema 9 Turnurile din Hanoi


hanoi(N) :- move(N, left, right, centre). move(0, _, _, _) :- !. move(N, A, B, C) :M is N-1, move(M, A, C, B), format("move a disc from the ~w pole to the ~w pole\n", [A,B]), move(M, C, B, A).

Interogari :
Hanoi ( 4 ) . move a disc from the left pole to the centre pole move a disc from the left pole to the right pole move a disc from the centre pole to the right pole move a disc from the left pole to the centre pole move a disc from the right pole to the left pole move a disc from the right pole to the centre pole move a disc from the left pole to the centre pole move a disc from the left pole to the right pole move a disc from the centre pole to the right pole move a disc from the centre pole to the left pole move a disc from the right pole to the left pole move a disc from the centre pole to the right pole move a disc from the left pole to the centre pole move a disc from the left pole to the right pole move a disc from the centre pole to the right pole

Problema 10 Numar prim


% P31 (**) Determina daca un numar dat este prim.

% is_prime(P) :- P is a prime number % (integer) (+) is_prime(2). is_prime(3). is_prime(P) :- integer(P), P > 3, P mod 2 =\= 0, \+ has_factor(P,3). % has_factor(N,L) :- N has an odd factor F >= L. % (integer, integer) (+,+) has_factor(N,L) :- N mod L =:= 0. has_factor(N,L) :- L * L < N, L2 is L + 2, has_factor(N,L2).

Interogari :
Is_prime ( 5) . Yes Is_prime ( 14) . no

APLICATIE IN PROLOG

Sistem expert n prolog


Bibliotec modern pentru inchirieri de crti

Student Calot Mihai , Grupa 242 Tema proiectului


Ghidarea clientilor care nu sunt foarte hotariti in alegerea unei carti pentru inchiriat, prin recomandari pe baza unui factor de certitudine.

Criteriile sistemului expert


Cartile se pot alege pe baza a 3 criterii.

1. Domenii
Optiuni posibile: economie,beletristica,muzica, it sau orice. Daca utilizatorul nu are o preferinta pentru gen, atunci alege orice.

2. Tip
Optiuni posibile: vechi,nou.

Acest criteriu face diferenta intre cartile vechi si cele nou aparute.

3. Format
Optiuni posibile: clasic,electronic sau oricare. Acest criteriu se refera la formatul in care se doreste a fi inchiriata cartea. In cazul in care utilizatorul este indecis, poate alege optiunea oricare.

Exemplu de rulare
In cele ce urmeaza afisam un exemplu practic de rulare. booting, please wait... SICStus 3 : #6: 1997 Oct 31 | ?- ['c:\\prj_log\\expert.pl'] . {consulting c:/prj_log/expert.pl...} {loading c:/program files/sicstus3/library/lists.ql...} {loaded c:/program files/sicstus3/library/lists.ql in module lists, 60 msec 53700 bytes} {loading c:/program files/sicstus3/library/system.ql...} {loaded c:/program files/sicstus3/library/system.ql in module system, 50 msec 32980 bytes} {c:/prj_log/expert.pl consulted, 210 msec 124548 bytes} | ?- incarca . Introduceti numele fisierului care doriti sa fie incarcat: |: 'c:\\prj_log\\carti.txt' . yes | ?- pornire . Introduceti una din urmatoarele optiuni:

(Incarca Consulta Reinitiaza Afisare_fapte Cum Iesire) |: consulta 'Domeniu?' ( economie , beletristica , muzica , it , orice ) : beletristica 'Tip:Recenta sau mai veche?' ( nou , vechi ) : nou 'Suport clasic sau electronic?' ( clasic , electronic , oricare ) : oricare

carte este muzica_stairway_to_heavenscurta_istorie_a_muzicii_pop_clasic factorul de certitudine este 20 carte este muzica_techno_o_generatie_in_extaz_electronic factorul de certitudine este 30 carte este beletristica_usainterzisa_clasic factorul de certitudine este 20 carte este beletristica_pururitanarinfasuratinpixeli_electronic factorul de certitudine este 80

Reguli
Baza de cunostinte contine 43 de reguli.

scopul este carte. regula 1 daca gen este economie atunci gen_econ. regula 2 daca gen este beletristica atunci gen_bel. regula 3 daca gen este muzica atunci gen_muz. regula 4 daca gen este it atunci gen_it. regula 5 daca gen este beletristica atunci gen_muz fc 30. regula 6 daca gen este muzica atunci gen_bel fc 30. regula 7 daca gen este beletristica atunci gen_it fc 50. regula 8 daca gen este it atunci gen_muz fc 10. regula 9 daca gen este muzica atunci gen_it fc 10. regula 10 daca gen este economie atunci gen_it fc 20.

regula 11 daca gen este economie atunci gen_muz fc 50. regula 12 daca aparut este vechi atunci tip_v. regula 13 daca aparut este nou atunci tip_n. regula 14 daca suport este clasic atunci tip_clasic. regula 15 daca suport este electronic atunci tip_electronic. regula 16 daca suport este electronic atunci tip_clasic fc 30. regula 17 daca suport este clasic atunci tip_electronic fc 30. regula 18 daca gen_econ si tip_v si tip_clasic atunci carte este economie_ManagementStrategic_clasic. regula 19 daca gen_econ si tip_v si tip_electronic atunci carte este economie_ManagementStrategic_electronic. regula 20 daca gen_econ si tip_n si tip_electronic atunci carte este economie_SistemeInformationalePtManageri_electronic.

regula 21 daca gen_econ si tip_n si tip_clasic atunci carte este economie_SistemeInformationalePtManageri_clasic. regula 22 daca gen_bel si tip_v si tip_clasic atunci carte este beletristica_Antologie_de_proza_latina_medievala_clasic. regula 23 daca gen_bel si tip_v si tip_electronic atunci carte este beletristica_Antologie_de_proza_latina_medievala_electronic. regula 24 daca gen_bel si tip_n si tip_electronic atunci carte este beletristica_PururiTanarInfasuratInPixeli_electronic. regula 25 daca gen_bel si tip_n si tip_clasic atunci carte este beletristica_UsaInterzisa_clasic. regula 26 daca gen_muz si tip_v si tip_clasic atunci carte este muzica_VietileUnuiDirijor_clasic. regula 27 daca gen_muz si tip_v si tip_electronic atunci carte este muzica_VietileUnuiDirijor_electronic. regula 28 daca gen_muz si tip_n si tip_electronic

atunci carte este muzica_Techno_o_generatie_in_extaz_electronic. regula 29 daca gen_muz si tip_n si tip_clasic atunci carte este muzica_Stairway_to_heavenScurta_istorie_a_muzicii_pop_clasic. regula 30 daca gen_it si tip_v si tip_clasic atunci carte este it_Securitateainformatiilor_clasic. regula 31 daca gen_it si tip_v si tip_electronic atunci carte este it_LimbajulPascal_electronic. regula 32 daca gen_it si tip_n si tip_electronic atunci carte este it_Limbajul_Java_de_la_0_la_expert_electronic. regula 33 daca gen_it si tip_n si tip_clasic atunci carte este it_Limbajul_Java_de_la_0_la_expert_clasic. regula 34 daca gen este orice atunci gen este gen_bel. regula 35 daca gen este orice atunci gen este gen_econ. regula 36 daca gen este orice atunci gen este gen_muz. regula 37 daca gen este orice

atunci gen este gen_it. regula 38 daca suport este oricare atunci suport este tip_electronic. regula 39 daca suport este oricare atunci suport este tip_clasic. regula 40 daca tip_n atunci tip_electronic fc 80. regula 41 daca tip_v atunci tip_clasic fc 80. regula 42 daca tip_n atunci tip_clasic fc 20. regula 43 daca tip_v atunci tip_electronic fc 20. intreaba gen optiuni (economie, beletristica, muzica, it, orice) afiseaza 'Domeniu?'. intreaba aparut optiuni (nou, vechi) afiseaza 'Tip:Recenta sau mai veche?'. intreaba suport optiuni (clasic, electronic, oricare) afiseaza 'Suport clasic sau electronic?'.

:-use_module(library(lists)). :-use_module(library(system)). :-op(900,fy,not). :-dynamic fapt/3. :-dynamic interogat/1. :-dynamic scop/1. :-dynamic interogabil/3. :-dynamic regula/3.

% prolog are abilitatea de a lucra cu Definite clause grammars, extensie a gramaticilor indep. de context % ceea ce usureaza parsingul not(P) :- P,!,fail. not(_). scrie_lista([]) :-nl. scrie_lista([H|T]) :-write(H), tab(1), scrie_lista(T).

% afiseaza afiseaza_fapte :- write('Fapte existente in baza de cunostinte: ') , nl,nl, write('(Atribut,valoare) '), nl,nl, listeaza_fapte,nl. listeaza_fapte:-fapt(av(Atr,Val),FC,_),write('('),write(Atr),write(','),write(Val), write(')'),write(','), write(' certitudine ') ,FC1 is integer(FC),write(FC1),nl,fail. listeaza_fapte.

lista_float_int( [] , []) . lista_float_int( [Regula|Reguli], [Regula1|Reguli1]):-(Regula \== utiliz, Regula1 is integer(Regula); Regula==utiliz, Regula1=Regula) , lista_float_int(Reguli, Reguli1) . % principalul predicat al interfetei pornire :- retractall(interogat(_)) , retractall(fapt(_,_,_)), repeat, write('Introduceti una din urmatoarele optiuni: ') , nl,nl, write('(Incarca Consulta Reinitiaza Afisare_fapte Cum Iesire) '), nl,nl,write('|: '),citeste_linie([H|T]), executa([H|T]), H == iesire. executa([incarca]) :- incarca,!,nl, write('Fisierul dorit a fost incarcat'),nl. executa([consulta]) :- scopuri_princ, ! . executa([reinitiaza]) :-retractall(interogat(_)), retractall(fapt(_,_,_)) , !. executa([afisare_fapte]) :- afiseaza_fapte, ! . executa([cum|L]) :- cum(L),!. executa([iesire]):-!. executa([_]) :- write('Comanda incorecta! '),nl. scopuri_princ :-scop(Atr) , determina(Atr) , afiseaza_scop(Atr) , fail. scopuri_princ. determina(Atr) :-realizare_scop(av(Atr,_) ,_, [scop(Atr) ]) , ! . determina(_) . afiseaza_scop(Atr) :-nl,fapt(av(Atr,Val) ,FC,_) ,FC >= 20, scrie_scop(av(Atr,Val) ,FC) ,nl,fail. afiseaza_scop(_) :-nl,nl. scrie_scop(av(Atr,Val) ,FC) :-transformare(av(Atr,Val) , X), scrie_lista(X),tab(2), write(' ') ,write('factorul de certitudine este '), FC1 is integer(FC),write(FC1) .

% principalul predicat al programului, "engine"-ul inferentei este: realizare_scop(not Scop ,Not_FC, Istorie) :-realizare_scop(Scop, FC, Istorie) ,Not_FC is -FC, !. realizare_scop(Scop, FC, _) :-fapt(Scop,FC,_), !. realizare_scop(Scop, FC, Istorie) :-pot_interoga(Scop, Istorie) ,!, realizare_scop(Scop, FC, Istorie) . realizare_scop(Scop, FC_curent, Istorie) :-fg(Scop,FC_curent,Istorie).

fg(Scop,FC_curent,Istorie) :-regula(N, premise(Lista), concluzie(Scop,FC)), demonstreaza(N,Lista,FC_premise,Istorie), ajusteaza(FC,FC_premise,FC_nou) , actualizeaza(Scop, FC_nou, FC_curent,N) , FC_curent == 100,!. fg(Scop,FC,_) :- fapt(Scop,FC,_) . pot_interoga(av(Atr,_) , Istorie) :-not interogat(av(Atr,_)) , interogabil(Atr,Optiuni,Mesaj), interogheaza(Atr,Mesaj,Optiuni,Istorie),nl, asserta( interogat(av(Atr,_)) ). cum([]) :- write('Scop? '),nl,write('| : ') ,citeste_linie(Linie) ,nl,transformare(Scop,Linie), cum(Scop). cum(L) :-transformare(Scop,L),nl, cum(Scop). cum(not Scop) :-fapt(Scop,FC,Reguli),lista_float_int(Reguli, Reguli1) ,FC < -20,transformare(not Scop,PG),append(PG,[a,fost,derivat,cu, ajutorul, 'regulilor:' |Reguli1],LL),scrie_lista(LL) ,nl,afis_reguli(Reguli) ,fail. cum(Scop) :-fapt(Scop, FC, Reguli) ,lista_float_int(Reguli, Reguli1) , FC > 20, transformare(Scop, PG) ,append(PG,[a,fost,derivat,cu, ajutorul, 'regulilor:' |Reguli1],LL),scrie_lista(LL) ,nl,afis_reguli(Reguli) , fail. cum(_) . afis_reguli([]). afis_reguli([N | X]) afis_regula(N) , premisele(N) , afis_reguli(X) .

:-

afis_regula(N) :regula(N, premise(Lista_premise) , concluzie(Scop,FC)) ,NN is integer(N) , scrie_lista(['regula ' ,NN]), scrie_lista([' Daca' ]) , scrie_lista_premise(Lista_premise) , scrie_lista([' Atunci' ]) , transformare(Scop, Scop_tr) , append([' '],Scop_tr,L1) , FC1 is integer(FC) , append(L1, [FC1] ,LL) , scrie_lista(LL) ,nl. scrie_lista_premise([]) . scrie_lista_premise([H | T]) :transformare(H, H_tr) , tab(5),scrie_lista(H_tr), scrie_lista_premise(T) . transformare(av(A,da), [A]) :- !. transformare(not av(A,da), [not,A]) :- !. transformare(av(A,nu),[not ,A]) :- !. transformare(av(A, V) , [A,este,V]) . premisele(N) :regula(N, premise(Lista_premise), _) , !, cum_premise(Lista_premise). cum_premise([]) . cum_premise([Scop | X]) :cum(Scop) , cum_premise(X) . interogheaza(Atr,Mesaj,[da,nu],Istorie) :!,write(Mesaj),nl,

de_la_utiliz(X,Istorie, [da,nu]) , det_val_fc(X,Val,FC) , asserta( fapt(av(Atr,Val),FC,[utiliz] ) ). interogheaza(Atr,Mesaj,Optiuni,Istorie) :write(Mesaj),nl, citeste_opt(VLista,Optiuni,Istorie), assert_fapt(Atr,VLista). citeste_opt(X,Optiuni, Istorie) :-append(['('],Optiuni,Opt1), append(Opt1,[')'] ,Opt) , scrie_lista(Opt) , de_la_utiliz(X,Istorie,Optiuni) . de_la_utiliz(X, Istorie ,Lista_opt) :-repeat,write(' : ') , citeste_linie(X) , proceseaza_raspuns(X, Istorie,Lista_opt) . proceseaza_raspuns([de_ce] , Istorie , _) :-nl,afis_istorie(Istorie) , ! ,fail. proceseaza_raspuns([X] ,_,Lista_opt) :member(X,Lista_opt) . proceseaza_raspuns([X,fc,FC] ,_,Lista_opt) :member(X,Lista_opt) ,float(FC) . assert_fapt(Atr, [Val, fc, FC ]) :!,asserta( fapt(av(Atr,Val),FC,[utiliz]) ). assert_fapt(Atr, [Val]) :asserta( fapt(av(Atr,Val),100,[utiliz])). det_val_fc([nu] ,da, -100) . det_val_fc([nu,FC] ,da,NFC) :- NFC is -FC. det_val_fc([nu, fc, FC] , da,NFC) :- NFC is -FC. det_val_fc([Val, FC] ,Val, FC) . det_val_fc([Val, fc, FC] ,Val, FC) . det_val_fc([Val] ,Val, 100) . afis_istorie([]) :- nl. afis_istorie([scop(X) | T]) :-scrie_lista([scop,X]),!, afis_istorie(T) . afis_istorie([N|T]) :afis_regula(N),!,afis_istorie(T). demonstreaza(N,ListaPremise,Val_finala,Istorie):-dem(ListaPremise,100,Val_finala,[N|Istorie]),!. dem([] ,Val_finala,Val_finala,_) . dem([H|T], Val_actuala,Val_finala,Istorie) realizare_scop(H,FC,Istorie) , Val_interm is min(Val_actuala , FC) , Val_interm >= 20, dem(T,Val_interm,Val_finala,Istorie) . :-

actualizeaza(Scop, FC_nou, FC, RegulaN) :fapt(Scop,FC_vechi,_) , combina(FC_nou,FC_vechi,FC), retract( fapt(Scop ,FC_vechi,Reguli_vechi) ) , asserta( fapt(Scop,FC,[RegulaN | Reguli_vechi]) ),!.

actualizeaza(Scop,FC,FC,RegulaN) :asserta( fapt(Scop,FC,[RegulaN]) ). ajusteaza(FC1,FC2,FC) :X is FC1 * FC2 / 100, FC is round(X). combina(FC1,FC2,FC) :FC1 >= 0,FC2 >= 0, X is FC2*(100 - FC1)/100 + FC1, FC is round(X). combina(FC1,FC2,FC) :FC1 < 0,FC2 < 0, X is -( -FC1 -FC2 *(100 + FC1)/100), FC is round(X). combina(FC1,FC2,FC) :(FC1 < 0; FC2 < 0), (FC1 > 0; FC2 > 0), FCM1 is abs(FC1),FCM2 is abs(FC2), MFC is min(FCM1,FCM2), X is 100 *(FC1 + FC2) /(100 - MFC), FC is round(X). incarca :write('Introduceti numele fisierului care doriti sa fie incarcat: ') , nl, write('|: '), read(F) , file_exists(F) , ! , incarca(F) . incarca:-write('Nume incorect de fisier! '),nl,fail. incarca(F) :retractall(interogat(_)),retractall(fapt(_,_,_)), retractall(scop(_)) , retractall(interogabil(_,_,_)), retractall(regula(_,_,_)) , see(F),incarca_reguli,seen,!. incarca_reguli :repeat,citeste_propozitie(L) , proceseaza(L),L == [end_of_file],nl. proceseaza([end_of_file]) :-! . proceseaza(L) :trad(R,L,[]),assertz(R), !. trad(scop(X)) --> [scopul ,este,X] . trad(scop(X)) --> [scopul,X] . trad(interogabil(Atr,M, P)) --> [intreaba,Atr] ,lista_optiuni(M) ,afiseaza(Atr,P) . trad(regula(N,premise(Daca) , concluzie(Atunci,F))) --> identificator(N) , daca(Daca) , atunci(Atunci, F) . trad(' Eroare la parsare'-L, L, _) . lista_optiuni(M) --> [optiuni , '('] , lista_de_optiuni(M) . lista_de_optiuni([Element]) --> [Element, ')']. lista_de_optiuni([ Element | T ]) --> [Element] , lista_de_optiuni(T) . afiseaza(_,P) --> [afiseaza,P] . afiseaza(P,P) --> []. identificator(N) --> [regula,N] . daca(Daca) --> [daca] , lista_premise(Daca) . lista_premise([Daca]) --> propoz(Daca) , [atunci] .

lista_premise([Prima| Celalalte]) --> propoz(Prima) , [si] ,lista_premise(Celalalte) . lista_premise([Prima| Celalalte]) --> propoz(Prima) ,[','] , lista_premise(Celalalte) . atunci(Atunci, FC) --> propoz(Atunci) , [fc] , [FC] . atunci(Atunci ,100) --> propoz(Atunci) . propoz(not( av(Atr,da))) --> [not,Atr] . propoz(av(Atr, Val)) --> [ Atr, este, Val ]. propoz(av(Atr, da)) --> [Atr]. citeste_linie([Cuv | Lista_cuv]) :-get0(Car), citeste_cuvant(Car, Cuv, Car1) , rest_cuvinte_linie(Car1, Lista_cuv) . % -1 este codul ASCII pt EOF rest_cuvinte_linie(-1, []):-!. rest_cuvinte_linie(Car, []) :-(Car==13;Car==10) , !. rest_cuvinte_linie(Car, [Cuv1 | Lista_cuv]) :-citeste_cuvant(Car,Cuv1,Car1), rest_cuvinte_linie(Car1, Lista_cuv) . citeste_propozitie([Cuv|Lista_cuv]) :get0(Car) ,citeste_cuvant(Car, Cuv, Car1), rest_cuvinte_propozitie(Car1, Lista_cuv) . rest_cuvinte_propozitie(-1, []):-!. rest_cuvinte_propozitie(Car, []) :-Car==46, ! . rest_cuvinte_propozitie(Car, [Cuv1 | Lista_cuv]) :-citeste_cuvant(Car, Cuv1, Car1) , rest_cuvinte_propozitie(Car1,Lista_cuv). citeste_tot_numarul(Caracter,Numar,Caracter1) :-determina_lista(Lista1,Caracter1) , append([Caracter] ,Lista1,Lista) , transforma_lista_numar(Lista, Numar) . determina_lista(Lista,Caracter1) :-get0(Caracter),(caracter_numar(Caracter) , determina_lista(Lista1,Caracter1) , append([Caracter],Lista1,Lista) ; \+(caracter_numar(Caracter)) , Lista=[] ,Caracter1=Caracter) . transforma_lista_numar([] ,0) . transforma_lista_numar([H | T] ,N) :transforma_lista_numar(T ,NN) , lungime(T,L), Aux is exp(10,L) , HH is H-48,N is HH*Aux+NN. lungime([],0). lungime([_ |T] , L):lungime(T,L1), L is L1+1. % 39 este codul ASCII pt ' pana_la_urmatorul_apostrof(Lista_caractere) :-get0(Caracter), (Caracter == 39,Lista_caractere=[Caracter] ; Caracter\==39, pana_la_urmatorul_apostrof(Lista_caractere1) , Lista_caractere= [Caracter |Lista_caractere1]) . citeste_cuvant(-1,end_of_file, -1) :-! . citeste_cuvant(Caracter,Cuvant,Caracter1) :caracter_cuvant(Caracter) ,! , name(Cuvant, [Caracter]),get0(Caracter1). citeste_cuvant(Caracter, Numar, Caracter1) :caracter_numar(Caracter) ,!, citeste_tot_numarul(Caracter, Numar, Caracter1) .

citeste_cuvant(Caracter, Cuvant, Caracter1) :-Caracter==39,! , pana_la_urmatorul_apostrof(Lista_caractere) , L= [Caracter | Lista_caractere] , name(Cuvant, L),get0(Caracter1). citeste_cuvant(Caracter,Cuvant,Caracter1) :caractere_in_interiorul_unui_cuvant(Caracter) ,!,((Caracter>64,Caracter<91) ,!, Caracter_modificat is Caracter+32; Caracter_modificat is Caracter) , citeste_intreg_cuvantul(Caractere,Caracter1) , name(Cuvant, [Caracter_modificat | Caractere]) . citeste_cuvant(_, Cuvant, Caracter1) :get0(Caracter) , citeste_cuvant(Caracter, Cuvant, Caracter1) . caracter_cuvant(C) :member(C,[44,59,58,63,33,46,41,40]) . citeste_intreg_cuvantul(Lista_Caractere, Caracter1) :get0(Caracter), (caractere_in_interiorul_unui_cuvant(Caracter) , ((Caracter>64,Caracter<91) ,!, Caracter_modificat is Caracter+32; Caracter_modificat is Caracter), citeste_intreg_cuvantul(Lista_Caracterel, Caracter1) , Lista_Caractere= [Caracter_modificat | Lista_Caracterel] ; \+(caractere_in_interiorul_unui_cuvant(Caracter)) , Lista_Caractere=[] , Caracter1=Caracter) . % am specificat codurile ASCII pentru , ; : ? ! . ( ) caractere_in_interiorul_unui_cuvant(C) :C>64,C<91;C>47,C<58; C==45 ;C==95 ;C>96, C<123. caracter_numar(C):- C<58,C>=48.