Documente Academic
Documente Profesional
Documente Cultură
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]
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 ? ;
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
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
:- 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
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]),
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).
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).
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 :
% 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 :
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
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 */
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).
[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]
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.
% 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
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).
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) (?,+,?,+)
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
% 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
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.