Documente Academic
Documente Profesional
Documente Cultură
PROIECT 1
1.
% Problema discreta a rucsacului
subl([],[]).
subl([H|T],[H|T1]):-subl(T,T1).
subl(L,[_|T1]):-subl(L,T1).
suma([],0,0).
suma([ob(G,V)|T],R,R1):-suma(T,SGT,SVT),R is G+SGT,R1 is V+SVT.
solutieposibila(G,L,R):-subl(R,L),suma(R,SGR,SVR),SGR=G.
Interogari:
| ?- solutieposibila(120,[ob(15,30),ob(105,30),ob(90,2),ob(15,5)],R) .
R = [ob(15,30),ob(105,30)]
R=[ob(15,30),ob(90,2),ob(15,5)]
R=[ob(105,30),ob(15,5)]
| ?- solutieposibila(100,[ob(10,30),ob(28,30),ob(90,2)],R) .
R = [ob(10,30),ob(90,2)] ?
| ?- solutieposibila(120,[ob(15,30),ob(40,30),ob(90,2),ob(15,5)],R) .
R = [ob(15,30),ob(90,2),ob(15,5)] ?
| ?- solutieposibila(120,[ob(15,30),ob(40,30),ob(90,2),ob(5,5)],R) .
1
no
2.
% Determina daca un nr este sau nu prim.
prim(2) .
prim(3).
prim(P) :-
integer(P) ,
P>3,
P mod 2 =\= 0,
\+ divide(P,3) .
% predicatul divide(P,L) :
% nr P se divide cu un nr F >= L
Interogari:
| ?- prim(13) .
yes
| ?- prim(55) .
no
| ?- prim(59) .
yes
| ?- prim(124367) .
yes
| ?- prim(3642156348) .
no
3.
% Lista de nr prime intr-un anumit interval.
prim(2) .
prim(3).
2
prim(P) :- integer(P) , P > 3 , P mod 2 =\= 0, \+ divide(P,3) .
p_list(A,B,[]) :- A > B, !.
p_list(A,B,[A|L]) :- prim(A), !, next(A,A1), p_list(A1,B,L).
p_list(A,B,L) :- next(A,A1), p_list(A1,B,L).
next(2,3) :- !.
next(A,A1) :- A1 is A + 2.
Interogari:
| ?- prime_list(6,200,L) .
L = [7,11,13,17,19,23,29,31,37,41|...] ?
| ?- prime_list(1,24,L) .
L = [2,3,5,7,11,13,17,19,23] ?
| ?- prime_list(6,3,L) .
L = [] ?
| ?- prime_list(7,13,L) .
L = [7,11,13] ?
4.
% Conjectura lui Goldbach.
% Conjectura lui Goldbach afirma ca fiecare numar par mai mare ca 2 poate fi scris
% ca suma de 2 nr prime. Exemplu: 28 = 5 + 23 .
% Ea nu a fost demonstrata, dar a fost verificata pana la numere foarte mari.
prim(2) .
prim(3).
3
divide(N,L) :- N mod L =:= 0.
divide(N,L) :- L * L < N, L2 is L + 2, divide(N,L2).
goldbach(4,[2,2]) :- !.
goldbach(N,L) :- N mod 2 =:= 0, N > 4, goldbach(N,L,3).
goldbach(N,[P,Q],P) :- Q is N - P, prim(Q), !.
goldbach(N,L,P) :- P < N, next_prim(P,P1), goldbach(N,L,P1).
next_prim(P,P1) :- P1 is P + 2, prim(P1), !.
next_prim(P,P1) :- P2 is P + 2, next_prim(P2,P1).
Interogari:
| ?- goldbach(700,L) .
L = [17,683] ?
| ?- goldbach(4,L) .
L = [2,2] ?
| ?- goldbach(44,L) .
L = [3,41] ?
| ?- goldbach(15,L) .
no
| ?- goldbach(36,L) .
L = [5,31] ?
5.
% Tabela de adevar pentru expresii logice.
% Sa se defineasca predicatele and, or, nand, nor, xor, impl si equ (echivalenta)
% care reusesc sau esueaza in functie de operatori.
% Apoi sa se defineasca predicatul table care construieste
% tabela de adevar pentru o expresie logica data.
not(A) :- \+ A .
and(A,B) :- A, B.
or(A,_) :- A.
or(_,B) :- B.
4
equ(A,B) :- or( and(A,B), and( not(A),not(B) ) ).
xor(A,B) :- not(equ(A,B)).
nor(A,B) :- not(or(A,B)).
nand(A,B) :- not(and(A,B)).
impl(A,B) :- or(not(A),B).
bind(true).
bind(fail).
Interogari:
?- table(A,B,and(A,or(A,B))).
true true true
true fail true
fail true fail
fail fail fail
| ?- table(A,B,and(A,B)) .
true true true
true fail fail
fail true fail
fail fail fail
| ?- table(A,B,xor(A,B)) .
true true fail
true fail true
fail true true
fail fail fail
| ?- table(A,B,or(A,B)) .
true true true
true fail true
fail true true
fail fail fail
5
| ?- table(A,B,nor(A,B)) .
true true fail
true fail fail
fail true fail
fail fail true
| ?- table(A,B,equ(A,B)) .
true true true
true fail fail
fail true fail
fail fail true
| ?- table(A,B,impl(A,B)) .
true true true
true fail fail
fail true true
fail fail true
6.
% Se repeta elementele unei liste de n ori.
% Exemplu: repeta([a,b,c],2,L)
% L = ([a,a,b,b,c,c]) .
% predicatul repeta(L1,N,L2) :
% L2 este obtinut prin repetarea elementelor L1 de N ori
% predicatul repeta(L1,N,L2,K) :
% L2 este obtinut din L1 prin repetarea primului element al lui L1 de K ori,
% iar a restului elementelor de N ori.
repeta(L1,N,L2) :- repeta(L1,N,L2,N).
repeta([],_,[],_).
repeta([_|A],N,B,0) :- repeta(A,N,B,N).
repeta([X|A],N,[X|B],K) :- K > 0, K1 is K - 1, repeta([X|A],N,B,K1).
Interogari:
| ?- repeta([a,b,c],2,L) .
L = [a,a,b,b,c,c]
| ?- repeta([a,b,c],3,L) .
L = [a,a,a,b,b,b,c,c,c]
| ?- repeta([a,b,c,d],3,L) .
6
L = [a,a,a,b,b,b,c,c,c,d|...]
| ?- repeta([a,b,c,d],1,L) .
L = [a,b,c,d]
| ?- repeta([a,b,c,d],0,L) .
L = []
| ?- repeta([],3,L) .
L = []
7.
% Extrage o sublista dintr-o lista.
% predicatul extrage(L1,I,K,L2) :
% lista L2 se obtine extragand elementele listei L1 intre indicii I si K
extrage([X|_],1,1,[X]) .
extrage([X|A],1,K,[X|B]) :-
K > 1,
K1 is K - 1 ,
extrage(A,1,K1,B) .
extrage([_|A],I,K,B) :-
I>1,
I1 is I - 1 ,
K1 is K - 1 ,
extrage(A,I1,K1,B) .
Interogari:
| ?- extrage([a,b,c,d,e,f,g,h,i,j],2,5,L) .
L = [b,c,d,e] ?
yes
| ?- extrage([a,b,c,d,e,f,g,h,i,j],2,15,L) .
no
| ?- extrage([a,b,c,d,e,f,g,h,i,j],1,10,L) .
L = [a,b,c,d,e,f,g,h,i,j] ?
yes
| ?- extrage([a,b,c,d,e,f,g,h,i,j],1,6,L) .
L = [a,b,c,d,e,f] ?
7
yes
| ?- extrage([a,b,c,d,e,f,g,h,i,j],6,3,L) .
no
| ?- extrage([a,b,c,d,e,f,g,h,i,j],6,6,L) .
L = [f] ?
yes
8.
% Puzzle aritmetic:
% Exemplu:
% Dandu-se lista de numere [2,3,5,7,11] se poate forma ecuatia
% 2-3+5+7 = 11 sau 2 = (3*5+7)/11 sau inca 10.
% equation(L,LT,RT) :-
% L este lista de numere care sunt frunzele in termenii aritmetici LT si RT,
% termenul stang si drept. Ecuatia va avea acelasi rezultat pt termenul stang si
% pentru cel drept.
equation(L,LT,RT) :-
split(L,LL,RL), % descompune lista L in LL si RL
term(LL,LT), % construieste termenul stang
term(RL,RT), % construieste termenul drept
LT =:= RT. % evalueaza si compara termenii
% term(L,T) :-
% L este lista nr care sunt frunze in termenul aritmetic T, de la stanga la dreapta
% binterm(LT,RT,T) :-
8
% T este un termen binar combinat, construit din termenii stang, LT, si drept, RT
binterm(LT,RT,LT+RT).
binterm(LT,RT,LT-RT).
binterm(LT,RT,LT*RT).
binterm(LT,RT,LT/RT) :- RT =\= 0. % evita impartirea la 0
% split(L,L1,L2) :-
% imparte lista L in liste nevide L1 si L2 a.i. concatenate dau L
do(L) :-
equation(L,LT,RT),
write(LT),write(' = '),write(RT),
nl,
fail.
do(_).
Interogari:
| ?- do([2,3,5,7,11]) .
2 = 3-(5+(7-11))
2 = 3-(5+7-11)
2 = 3-5-(7-11)
2 = 3-(5+7)+11
2 = 3-5-7+11
2 = (3*5+7)/11
2*(3-5) = 7-11
2-(3-(5+7)) = 11
2-(3-5-7) = 11
2-3+(5+7) = 11
2-(3-5)+7 = 11
2-3+5+7 = 11
yes
| ?- do([2,3,5,7]) .
yes
9
| ?- do([2,3,5]) .
2+3 = 5
yes
| ?- do([23,3,5,21,3,14]) .
23 = 3+5*(21-(3+14))
23 = 3+5*(21-3-14)
23+3 = 5-(21-3*14)
23+3 = 5+(21/3+14)
23+3 = 5-21+3*14
23+3 = 5+21/3+14
23-3 = 5*(21-(3+14))
23-3 = 5*(21-3-14)
23+(3-5) = 21/3+14
23+3*5 = 21+(3+14)
23+3*5 = 21+3+14
23+3-5 = 21/3+14
(23-3)/5 = 21-(3+14)
(23-3)/5 = 21-3-14
23+(3-(5-21)) = 3*14
23+(3-5+21) = 3*14
23+(3*5-21) = 3+14
23+3-(5-21) = 3*14
23+(3-5)+21 = 3*14
23+3*5-21 = 3+14
23+3-5+21 = 3*14
23+(3-(5+21/3)) = 14
23+(3-5-21/3) = 14
23+(3*5-(21+3)) = 14
23+(3*5-21-3) = 14
23+3-(5+21/3) = 14
23+(3-5)-21/3 = 14
23+3*5-(21+3) = 14
23+3-5-21/3 = 14
(23+(3-(5-21)))/3 = 14
(23+(3-5+21))/3 = 14
23+(3*5-21)-3 = 14
(23+3-(5-21))/3 = 14
(23+(3-5)+21)/3 = 14
23+3*5-21-3 = 14
(23+3-5+21)/3 = 14
yes
9.
% Numere
10
% Pe documentele oficiale, cum ar fi cecurile, numerele trebuie
% scrise cateodata si in cuvinte. De exemplu, 175 trebuie scris
% unu-sapte-cinci.
cuvinte1(0) :- !.
cuvinte1(N) :- N > 0,
Q is N // 10, R is N mod 10,
cuvinte1(Q), nr_cuvant(R,RW), liniuta(Q), write(RW).
liniuta(0) :- !.
liniuta(Q) :- Q > 0, write('-').
nr_cuvant(0,zero).
nr_cuvant(1,unu).
nr_cuvant(2,doi).
nr_cuvant(3,trei).
nr_cuvant(4,patru).
nr_cuvant(5,cinci).
nr_cuvant(6,sase).
nr_cuvant(7,sapte).
nr_cuvant(8,opt).
nr_cuvant(9,noua).
Interogari:
| ?- cuvinte(123) .
unu-doi-trei
yes
| ?- cuvinte(0) .
zero
yes
| ?- cuvinte(-56) .
no
| ?- cuvinte(35641) .
trei-cinci-sase-patru-unu
yes
11
| ?- cuvinte(9854030) .
noua-opt-cinci-patru-zero-trei-zero
yes
10.
% Testul de inteligenta al lui Einstein
% Reguli:
einstein(Case, Prop_Peste) :-
=(Case, [[casa, norvegian, _, _, _, _], _, [casa, _, _, _, lapte, _], _, _]),
membru([casa, britanic, _, _, _, rosu], Case),
membru([casa, suedez, caine, _, _, _], Case),
membru([casa, danez, _, _, ceai, _], Case),
dreapta([casa, _, _, _, _, verde], [casa, _, _, _, _, alb], Case),
membru([casa, _, _, _, cafea, verde], Case),
membru([casa, _, pasare, pallmall, _, _], Case),
12
membru([casa, _, _, dunhill, _, galben], Case),
langa([casa, _, _, marlboro, _, _], [casa, _, pisica, _, _, _], Case),
langa([casa, _, _, dunhill, _, _], [casa, _, cal, _, _, _], Case),
membru([casa, _, _, winfield, bere, _], Case),
langa([casa, norvegian, _, _, _, _], [casa, _, _, _, _, albastru], Case),
membru([casa, german, _, rothmans, _, _], Case),
langa([casa, _, _, marlboro, _, _], [casa, _, _, _, apa, _], Case),
membru([casa, Prop_Peste, peste, _, _, _], Case).
Interogare:
| ?- einstein(Case,Prop_Peste) .
Case = [[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]],
Prop_Peste = german ?
Yes
PROIECT 2
1) MAIMUłA
EnunŃul problemei:
Avem o maimuŃã într-o încapere. In mijlocul camerei se afla o banana atârnata de
tavan. MaimuŃa vrea sa ia banana dar nu poate ajunge pana la ea. In camera se mai afla o
cutie, poziŃionatã in dreptul ferestrei pe care maimuŃa o poate folosi. MaimuŃa poate
realiza urmãtoarele acŃiuni :
-sã meargã pe podea
-sã se urce pe cutie
-sã împingã cutia
-sã ia banana dacã stã pe cutie chiar sub bananã
Poate mamuŃa lua banana ?
Codul în Prolog:
%starile
13
stare(la_fereastra, pe_podea, la_fereastra , nu_are).
stare(la_fereastra, pe_cutie, la_fereastra, nu_are).
stare(mijloc, pe_podea, mijloc, nu_are).
stare(mijloc, pe_cutie, mijloc, nu_are).
stare(mijloc, pe_cutie, mijloc, are).
%miscarile
miscare(stare(P1,pe_podea,B,H),
merge(P1,P2),
stare(P2,pe_podea,B,H)).
%poate lua
poate_lua(stare(_,_,_,are)).
poate_lua(Stare1):- miscare(Stare1,M,Stare2),poate_lua(Stare2).
Interogãri:
EnunŃul problemei:
14
Se dã un automat nedeterminist reprezentat prin stãri şi tranziŃii , şi un şir . Se cere sã
se verifice dacã şirul respectiv va fi acceptat sau nu de cãtre automat . Automatul dat va
accepta un şir dacã se terminã cu literele “ab” şi il respinge în caz contrar.
Codul în Prolog:
%reprezentarea automatului
final( s3).
%acceptarea
accept( S, [ ] ) :-final( S ).
accept( S, [ X | Rest ] ):-
trans( S, X, S1),
accept( S1, Rest).
accept( S, String) :-
nul( S , S1 ),
accept( S1, String).
Interogãri:
15
3)PLANIFICAREA CALATORIILOR
EnunŃul problemei:
Avem o baza de cunoştinŃe care reŃine zborurile de pe un aeroport. Se cere ca
programul nostru sã rãspundã la urmãtoarele întrebãri:
-In ce zile ale sãptãmânii existã zbor direct între Londra şi Bucureşti?
-Cum se poate ajunge din Bucureşti în Roma, joia?
-Vrea sã cizitez Milan, Bucureşti si Viena cu plecare din Londra marŃi si revenirea în
Londra vineri. In ce ordine ar trebui sa vizitez orasele astfel încât sã nu am mai mult de
un zbor pe zi?
Codul în Prolog:
%rutele zborurilor
:-op(50,xfy,:).
zbor( Loc1, Loc2, Ziua, Fnum, Plec, Sos) :-
tabel_timp( Loc1 , Loc2, Lista_zbor),
16
membru( Plec / Sos / Fnum / Lista_zile , Lista_zbor),
ziua_zbor( Ziua, Lista_zile).
membru( X, [X|L] ).
membru( X, [Y|L] ) :- membru( X, L).
17
[ 8:30 / 11:20 / ba510 / mereu,
11:10 / 13:50 / az459 / mereu ] ).
tabel_timp( bucuresti, viena,
[ 11:30 / 12:40 / ju322 / [ma,jo] ] ).
tabel_timp( bucuresti, londra,
[ 11:10 / 12:20 / yu200 / [vi],
11:25 / 12:20 / yu212 / [du] ] ).
tabel_timp( milan, londra,
[ 9:10 / 10:00 / az458 / mereu,
12:20 / 13:10 / ba511 / mereu ] ).
tabel_timp( milan, viena,
[ 9:25 / 10:15 / sr621 / mereu,
12:45 / 13:35 / sr623 / mereu ] ).
tabel_timp( viena, bucuresti,
[ 13:30 / 14:40 / yu323 / [ma,jo] ] ).
tabel_timp( viena, londra,
[ 9:00 / 9:40 / ba613 / [lu,ma,mi,jo,vi,sa],
16:10 / 16:55 / sr806 / [lu,ma,mi,jo,vi,du] ] ).
tabel_timp( viena, milan,
[ 7:55 / 8:45 / sr620 / mereu ] ).
del(X,[X|T],T).
perm([],[]).
del(X,[Y|T],[Y|T1]):-del(X,T,T1).
insert(X,L,L1):-del(X,L1,L).
perm([X|L],P):-perm(L,L1),insert(X,L1,P).
Interogãri:
18
19
4) PROBLEMA CELOR 8 DAME
EnunŃul problemei:
Avem 8 dame şi trebuie sã le aşezãm pe o tablã de sah astfel încât sã nu se atace între
ele.
Codul în Prolog:
solutie( [] ).
solutie( [ X/Y | Altele] ) :-
solutie( Altele),
membru( Y, [1,2,3,4,5,6,7,8] ),
nu_ataca( X/Y, Altele).
nu_ataca( _, [] ).
nu_ataca( X/Y, [X1/Y1 | Altele] ):-
Y=\=Y1 ,
Y1-Y =\= X1-X,
Y1-Y =\= X-X1,
Y-Y1 =\=X1-X,
20
Y-Y1 =\= X-X1,
nu_ataca( X/Y, Altele).
membru( X, [ X|L ] ).
membru( X, [ Y|L ] ):- membru( X, L).
Interogãri:
.................
5)BUBBLESORT
Enuntul problemei:
Am o listã de întregi şi vreau sã o sortez folosind interschimbãri.
21
Codul în Prolog:
schimb([X,Y|Rest],[Y,X|Rest]):-X>Y.
schimb([Z|Rest],[Z|Rest1]):-schimb(Rest,Rest1).
Interogãri:
6)QUICKSORT
EnunŃul problemei:
Se dã o listã de întregi şi se cere sã se sorteze crescãtor.
Codul în Prolog:
quicksort( [] , [] ).
quicksort( [ X|Tail], Sortat) :-
desp( X, Tail, Mic, Mare),
quicksort( Mic, Sortatmic),
quicksort( Mare, Sortatmare),
conc( Sortatmic, [X | Sortatmare], Sortat).
desp( X, [], [], [] ).
desp( X, [Y | Tail], [Y|Mic], Mare) :-
( X > Y), !,
desp( X, Tail, Mic, Mare).
desp( X, [ Y | Tail], Mic, [Y | Mare] ) :-
desp( X, Tail, Mic, Mare).
conc( [], L, L).
conc( [ X|L1 ], L2, [ X|L3 ] ) :-
conc( L1, L2, L3).
22
Interogãri:
7) DERIVARE
EnunŃul problemei:
Se dã o expresie si se cere sã se deriveze.
Codul în Prolog:
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/V,X,(DU*V-U*DV)/(^(V,2))) :-!,
d(U,X,DU),
d(V,X,DV).
d(^(U,N),X,DU*N*(^(U,N1))) :- !,
integer(N),
N1 is N-1,
d(U,X,DU).
d(-U,X,-DU) :- !,
d(U,X,DU).
d(exp(U),X,exp(U)*DU) :-!,
d(U,X,DU).
d(log(U),X,DU/U) :- !,
d(U,X,DU).
d(X,X,1) :- !.
d(_,_,0).
23
Interogãri:
8)PROGRAMATORI
EnunŃul problemei:
Codul în Prolog:
%fapte
nume(james).
24
nume(tom).
nume(bob).
nume(jim).
limbaj(html).
limbaj(cpp).
limbaj(java).
limbaj(prolog).
domeniu(mate).
domeniu(fizica).
domeniu(chimie).
domeniu(bio).
%reguli
regula1(Y,Z):-Y=bio,!,Z=java.
regula1(_,_).
regula2(X,Y,Z):-X=tom,!,Y\==mate,Z\==prolog,Z\==html.
regula2(_,_,_).
regula3(X,Y,Z):-X=james,!,Y\==mate,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).
25
Interogãri:
9) DENSITATE
EnunŃul problemei:
Se dã o bazã de cunoştinŃe, se cere sã se gãseascã Ńãrile cu denitatea populaŃiei
aproximativ egalã.
Codul în Prolog:
% populations in 100000's
pop(china, 8250).
pop(india, 5863).
pop(ussr, 2521).
pop(usa, 2119).
pop(indonesia, 1276).
pop(japan, 1097).
26
pop(brazil, 1042).
pop(bangladesh, 750).
pop(pakistan, 682).
pop(w_germany, 620).
pop(nigeria, 613).
pop(mexico, 581).
pop(uk, 559).
pop(italy, 554).
pop(france, 525).
pop(philippines, 415).
pop(thailand, 410).
pop(turkey, 383).
pop(egypt, 364).
pop(spain, 352).
pop(poland, 337).
pop(s_korea, 335).
pop(iran, 320).
pop(ethiopia, 272).
pop(argentina, 251).
27
Interogãri:
EnunŃul problemei:
Prezumtii:
1.Exista 5 case fiecare de alta culoare.
2.In fiecare casa locuieste o singura persoana, fiecare de alta nationalitate
3.Fiecarui locatar ii place o anumita bautura, fumeaza o anumita marca de tigari si detine
un anumit animal de casa.
4.Nici una din cele 5 persoane nu bea aceeasi bautura, nu fumeaza aceeasi marca de
tigari, si nu detine acelasi animal de casa.
28
Se dau urmatoarele:
Codul în Prolog:
iright(L, R, [L | [R | _]]).
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).
member(X,[X|T]).
member(X,[H|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),
29
member([house, german, _, rothmans, _, _], Houses),
next_to([house, norwegian, _, _, _, _], [house, _, _, _, _, blue], Houses),
member([house, Fish_Owner, fish, _, _, _], Houses).
Interogãri:
PROIECT 3
Prolog – Teme
Autor – Dumitru Ciubatîi , Grupa 243 .
Tema 1 – Sudoku.
Enunt:
Sudoku reprezinta un joc clasic in care este dat un tabel compus din 9 x 9 patratele, unite
la randul sau in 9 blocuri de marime 3 x 3 ca in exemplul de mai jos. Unele patratele
contin initial cate o cifra cuprinsa intre 1 si 9 inclusiv. Scopul jocului este de a completa
restul patratelelor libere cu cifre astfel incat fiecare linie, fiecare coloana si fiecare bloc 3
x 3 sa contina toate cifrele de la 1 la 9.
Se cere un program prolog care sa rezolve acest joc.
30
Solutie:
:- use_module(library(clpfd)).
sudoku(
A1, A2, A3, A4, A5, A6, A7, A8, A9,
B1, B2, B3, B4, B5, B6, B7, B8, B9,
C1, C2, C3, C4, C5, C6, C7, C8, C9,
D1, D2, D3, D4, D5, D6, D7, D8, D9,
E1, E2, E3, E4, E5, E6, E7, E8, E9,
F1, F2, F3, F4, F5, F6, F7, F8, F9,
G1, G2, G3, G4, G5, G6, G7, G8, G9,
H1, H2, H3, H4, H5, H6, H7, H8, H9,
I1, I2, I3, I4, I5, I6, I7, I8, I9
) :-
31
domain(L, 1, 9),
% RANDURI
all_different([A1, A2, A3, A4, A5, A6, A7, A8, A9]),
all_different([B1, B2, B3, B4, B5, B6, B7, B8, B9]),
all_different([C1, C2, C3, C4, C5, C6, C7, C8, C9]),
all_different([D1, D2, D3, D4, D5, D6, D7, D8, D9]),
all_different([E1, E2, E3, E4, E5, E6, E7, E8, E9]),
all_different([F1, F2, F3, F4, F5, F6, F7, F8, F9]),
all_different([G1, G2, G3, G4, G5, G6, G7, G8, G9]),
all_different([H1, H2, H3, H4, H5, H6, H7, H8, H9]),
all_different([I1, I2, I3, I4, I5, I6, I7, I8, I9]),
% COLOANE
all_different([A1, B1, C1, D1, E1, F1, G1, H1, I1]),
all_different([A2, B2, C2, D2, E2, F2, G2, H2, I2]),
all_different([A3, B3, C3, D3, E3, F3, G3, H3, I3]),
all_different([A4, B4, C4, D4, E4, F4, G4, H4, I4]),
all_different([A5, B5, C5, D5, E5, F5, G5, H5, I5]),
all_different([A6, B6, C6, D6, E6, F6, G6, H6, I6]),
all_different([A7, B7, C7, D7, E7, F7, G7, H7, I7]),
all_different([A8, B8, C8, D8, E8, F8, G8, H8, I8]),
all_different([A9, B9, C9, D9, E9, F9, G9, H9, I9]),
% PATRATE 3x3
all_different([A1, A2, A3, B1, B2, B3, C1, C2, C3]),
all_different([A4, A5, A6, B4, B5, B6, C4, C5, C6]),
all_different([A7, A8, A9, B7, B8, B9, C7, C8, C9]),
labeling([], L),
afiseaza(L).
afiseaza(L) :- afiseaza(1,L).
afiseaza(X,[A|L]) :- X<81 -> write(A), Z is X mod 9 , ( Z=0,X>0 -> write('\n') ; write(',')
) , afiseaza(X+1,L) ; write(A) , write('\n') .
32
% exemplu din enunt
joc1 :- sudoku(
_,4,_,1,_,3,5,_,_,
7,_,_,_,_,_,_,1,8,
9,_,1,6,_,8,3,_,_,
1,_,_,4,_,_,6,_,_,
_,8,_,2,_,6,_,9,_,
_,_,2,_,_,9,_,_,4,
_,_,7,9,_,1,4,_,6,
4,9,_,_,_,_,_,_,3,
_,_,6,3,_,7,_,2,_
).
joc2 :- sudoku(
_,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,_
).
joc3 :- sudoku(
_,_,_,3,_,_,4,6,_,
_,_,9,8,_,_,_,_,2,
1,4,8,_,_,_,_,_,_,
_,1,3,5,8,_,_,4,_,
8,5,_,_,_,_,_,1,3,
_,2,_,_,1,3,7,8,_,
_,_,_,_,_,_,3,2,1,
5,_,_,_,_,_,7,8,_,
_,8,1,_,_,9,_,_,_
).
joc4 :- sudoku(
_,_,_,2,_,_,_,9,_,
6,3,_,_,4,_,_,_,8,
_,_,9,6,_,_,_,1,_,
_,7,6,_,_,_,_,_,9,
33
_,_,1,4,_,2,8,_,_,
3,_,_,_,_,_,1,7,_,
_,2,_,_,_,6,7,_,_,
9,_,_,_,2,_,_,5,1,
_,6,_,_,_,1,_,_,_
).
% un tabel curat
joc0 :- sudoku(
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_,
_,_,_,_,_,_,_,_,_
).
Exemple de rulare:
?- joc1.
2,4,8,1,7,3,5,6,9
7,6,3,5,9,4,2,1,8
9,5,1,6,2,8,3,4,7
1,7,9,4,8,5,6,3,2
5,8,4,2,3,6,7,9,1
6,3,2,7,1,9,8,5,4
3,2,7,9,5,1,4,8,6
4,9,5,8,6,2,1,7,3
8,1,6,3,4,7,9,2,5
?- joc2.
1,4,3,9,8,6,2,5,7
6,7,9,4,2,5,3,8,1
2,8,5,7,3,1,6,9,4
9,6,2,3,5,4,1,7,8
3,5,7,6,1,8,9,4,2
4,1,8,2,7,9,5,6,3
8,2,1,5,6,7,4,3,9
7,9,6,1,4,3,8,2,5
5,3,4,8,9,2,7,1,6
?- joc3.
34
no
?- joc4.
4,1,8,2,5,7,3,9,6
6,3,7,1,4,9,5,2,8
2,5,9,6,8,3,4,1,7
8,7,6,3,1,5,2,4,9
5,9,1,4,7,2,8,6,3
3,4,2,9,6,8,1,7,5
1,2,5,8,9,6,7,3,4
9,8,3,7,2,4,6,5,1
7,6,4,5,3,1,9,8,2
?- joc0.
1,2,3,4,5,6,7,8,9
4,5,6,7,8,9,1,2,3
7,8,9,1,2,3,4,5,6
2,1,4,3,6,5,8,9,7
3,6,5,8,9,7,2,1,4
8,9,7,2,1,4,3,6,5
5,3,1,6,4,2,9,7,8
6,4,2,9,7,8,5,3,1
9,7,8,5,3,1,6,4,2
35
Tema 2 – Numarul de componente conexe intr-un graf.
Enunt:
Solutie:
graf1:-abolish(nodes),abolish(vec),
asserta(nodes([a,b,c,d,e,f,g,h])),
asserta(vec(a,[b,c])),
asserta(vec(b,[a])),
asserta(vec(c,[a,d,e])),
asserta(vec(d,[c])),
asserta(vec(e,[c])),
asserta(vec(f,[g,h])),
asserta(vec(g,[f,h])),
asserta(vec(h,[f,g])).
graf2:-abolish(nodes),abolish(vec),
asserta(nodes([a,b,c,d,e,f,g,h,i,j,k,l,m])),
asserta(vec(a,[b,c,h])),
asserta(vec(b,[a])),
asserta(vec(c,[a])),
asserta(vec(d,[k,m])),
asserta(vec(e,[i,g])),
asserta(vec(f,[i,g])),
asserta(vec(g,[e,f])),
asserta(vec(h,[a])),
asserta(vec(i,[j,e,f])),
asserta(vec(j,[i,k])),
asserta(vec(k,[d,j])),
asserta(vec(l,[])),
asserta(vec(m,[d])).
% testele
test1:-graf1,comp.
test2:-graf2,comp.
36
% programul
comp:-clear,init,loop,write_res.
init:-nodes(L),init(L).
init(L):-assert(total(0)),list_noduri(L).
clear:-clear_coada,nodes(L),clear(L).
clear(L):-retract(total(X)),clear(L).
clear([X|L]):-retract(liber(X)),clear(L).
clear(L).
clear_coada:-retract(coada(X)),clear_coada.
clear_coada.
write_res:-retract(total(X)),write(X).
list_noduri([X]):-assert(liber(X)).
list_noduri([X|Y]):-assert(liber(X)),list_noduri(Y).
% simulam un ciclu
loop:-retract(liber(X)),push(X),parcurge,retract(total(T)),T1 is T+1,assert(total(T1)),loop.
loop.
parcurge:-pop(X),vec(X,V),get_free(V,L),push(L),parcurge.
parcurge.
get_free([],[]).
get_free([X|L],[X|K]):- retract(liber(X)),get_free(L,K).
get_free([X|L],K):- get_free(L,K).
get_free(X,[X|K]):- retract(liber(X)).
get_free(X,K).
pop(X):-retract(coada(X)).
37
Exemple de rulare:
?- test1.
2
?- test2.
3
38
Tema 3 –Cel mai scurt drum intre 2 varfuri intr-un graf.
Enunt:
Se da un graf nedirectionat: se da lista varfurilor sale si lista de muchii sub forma (a,b,c),
unde a si b sunt varfurile muchiei si c este costul ei.
Se cere un program prolog care sa afle si sa afiseze cel mai scurt drum de la un varf S la
un varf F in graful dat.
Solutie:
graf2:-abolish(nodes),abolish(vec),
assert(nodes([a,b,c,d,e,f,g,h])),
assert(vec(a,b,5)),
assert(vec(a,d,6)),
assert(vec(a,g,4)),
assert(vec(b,f,3)),
assert(vec(c,d,3)),
assert(vec(c,f,6)),
assert(vec(e,f,3)),
assert(vec(e,g,2)),
assert(vec(e,h,2)),
assert(vec(f,h,1)).
% testele
test1:-graf1,drum(a,c).
test2:-graf1,drum(d,b).
test3:-graf1,drum(a,e).
test4:-graf2,drum(b,e).
test5:-graf2,drum(h,b).
test6:-graf2,drum(d,e).
test7:-graf2,drum(a,h).
39
% functii pentru muchii
is_connect(X,Y):-vec(X,Y,_);vec(Y,X,_).
cost(X,Y,Z):-vec(X,Y,C),Z is C;vec(Y,X,C),Z is C.
% initializare
clear:-nodes(L),clear_vl(L),clear_prec,clear_best(L),(retract(dst(X))->true;true).
clear_vl([X|L]):-set_vl(X,0),clear_vl(L).
clear_vl([]).
clear_best([X|L]):-set_best(X,1000000),clear_best(L).
clear_best([]):-set_best(z,1000000).
clear_prec:-abolish(prec).
clear_prec.
init(S):-set_vl(S,1),set_best(S,0).
drum(S,F):-clear,init(S),loop(F),get_best(F,Res),afiseaza_drum(S,F),write('\nLungimea
drumului - '),write(Res).
loop(F):-get_min(F) ; get_min(X), ( get_best(X,1000000) ; set_vl(X,2), update(X) ,
loop(F) ) .
afiseaza_drum(S,S):-write(S).
afiseaza_drum(S,F):-get_prec(F,X),afiseaza_drum(S,X),write(-),write(F).
% ---
get_min(X):-nodes(L),get_free_node(Y),get_min(Y,L,X).
get_min(X,[Y|L],X):-
get_vl(Y,C),C==1,get_best(Y,BY),get_best(X,BX),BY<BX,get_min(X,L,X).
get_min(X,[Y|L],Z):- get_min(X,L,Z).
get_min(X,[],X).
get_free_node(X):-nodes(L),get_free_node(X,L).
get_free_node(Y,[Y|L]):-get_vl(Y,V),V==1.
get_free_node(X,[Y|L]):-get_free_node(X,L).
% ---
update(X):-nodes(L),update(X,L).
update(X,[Y|L]):- ( X\==Y, get_best(X,BX) , get_vl(Y,VY) , cost(X,Y,C) , CCost is
BX+C , get_best(Y,BY) , (VY==0 ; VY==1 , CCost<BY) , set_vl(Y,1),
set_best(Y,CCost), set_prec(Y,X) ; true ) , update(X,L).
40
update(X,[]).
% ---
set_vl(X,Y):-retract(vl(X,Z)),assert(vl(X,Y));assert(vl(X,Y)).
get_vl(X,Y):-retract(vl(X,Y)),assert(vl(X,Y)).
set_best(X,Y):-retract(best(X,Z)),assert(best(X,Y));assert(best(X,Y)).
get_best(X,Y):-retract(best(X,Y)),assert(best(X,Y)).
Exemple de rulare:
?- test1.
a-b-c
Lungimea drumului - 20
yes
?- test2.
d-a-b
Lungimea drumului - 33
yes
?- test3.
a-b-c-e
Lungimea drumului - 25
yes
?- test4.
b-f-e
Lungimea drumului - 6
yes
?- test5.
h-f-b
Lungimea drumului - 4
yes
?- test6.
d-c-f-e
Lungimea drumului - 12
yes
41
?- test7.
a-b-f-h
Lungimea drumului - 9
yes
PROIECT 4
Leuca Petrica
grupa 242
introdu:-
write('introdu a= '),read(A),
write('introdu b= '),read(B),
write('introdu c= '),read(C),
A>=0,B>=0,C>=0,A<(B+C),B<(C+A),C<(A+B),
write('Aceste numere sunt laturile unui triunghi '),nl.
yes
member(X,[X|_]).
member(X,[_|T]):- member(X,T).
set1([],[]):- !.
set1([H|T],R):- member(H,T), set1(T,R), !.
42
set1([H|T],[R|Rest]):- set1(T,Rest).
I = [a,b,c] ?
yes
start:- citire(A,B,C),rezolvare(A,B,C),!,continuare.
citire(A,B,C):-write('Dati coeficientii:'),nl,
write('A='),read(A),nl,
write('B='),read(B),nl,
write('C='),read(C),nl.
% calculam delta
delta(A,B,C,R):- D is (B*B-4*A*C),
D>=0,R is (sqrt(D)).
%pentru A diferit de 0
rezolvare(A,B,C):- A=\=0,delta(A,B,C,R),R>=0,
X1 is (-B+R)/(2*A), X2 is (-B-R)/(2*A),
write('Solutiile ecuatiei sunt '),
write('x1='),write(X1),write(' x2='),write(X2),nl.
continuare:-write('Doriti sa continuam(da,yes)?='),read(X),
(X=da;X=d;X=a;X=y;X=ye;X=yes),start.
Apel :
43
?- start.
Dati coeficientii:
A=1
.
B=2.
C=1.
4. Lucrul cu multimi
% Reuniunea si intersectia a 2 multimi
% predicatul membru
member(X,[X|_]).
member(X,[_|T]):-member(X,T).
% verifica daca o lista e multime.
set([]).
set([X|T]):-not member(X,T), set(T).
% reuniunea a 2 multimi
union([],X,X):-!.
union([X|R],Y,Z):-member(X,Y), union(R,Y,Z), !.
union([X|R],Y,[X|Z]):-union(R,Y,Z).
%intersectia a 2 multimi
intersect([],X,[]):-!.
intersect([X|R],Y,[X|T]):-member(X,Y), intersect(R,Y,T), !.
intersect([X|R],Y,L):-intersect(R,Y,L).
Apel:
?- union([a,b,c],[d],R).
R = [a,b,c,d] ?
yes
| ?- intersect([a,b,c],[a,c],R).
R = [a,c] ?
yes
44
init(stare(1,C)).
final(stare(4,[])).
% automatul
% -1---a-->2--a-->3--a-->4-----
% ||----b--|--b---| |-a,b-|
% ||
% -b
arc(1,2,[a]).
arc(1,1,[b]).
arc(2,3,[a]).
arc(2,1,[b]).
arc(3,2,[b]).
arc(3,4,[a]).
arc(4,4,[a,b]).
go1:-write('da cuvant='),read(C),init(stare(S,C)),final(F),
drum(stare(S,C),F,Rez),write([stare(S,C)|Rez]).
de_la(stare(X,[H|T]),stare(Y,T)):-arc(X,Y,L),member(H,L).
drum(X,X,[]).
drum(X,Y,[Z|T]):-de_la(X,Z),drum(Z,Y,T).
member(X,[X|_]).
member(X,[_|T]):-member(X,T).
Apel:
?- go1.
da cuvant=[a,a,a,a,b,b].
[stare(1,[a,a,a,a,b,b]),stare(2,[a,a,a,b,b]),stare(3,[a,a,b,b]),stare(4,[a,b,b]),stare(4,[b,b]),sta
re(4,[b]),stare(4,[])]
yes
member(X,[X|T]).
member(X,[H|T]):-member(X,T).
iright(L, R, [L | [R | _]]).
45
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).
Apel:
?- einstein(X,Y).
X=
[[house,norwegian,cat,dunhill,water,yellow],[house,dane,horse,marlboro,tea,blue],[house
,brit,bird,pallmall,milk,red],[house,german,fish,rothmans,coffee,green],[house,swede,dog
,winfield,beer,white]],
Y = german ? ;
no
7.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=[
46
[_,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 :-
47
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),
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),
%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),
48
%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).
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).
49
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).
Apel:
?- test1.
[9,6,3,1,7,4,2,5,8]
[1,7,8,3,2,5,6,4,9]
[2,5,4,6,8,9,7,3,1]
[8,2,1,4,3,7,5,9,6]
[4,9,6,8,5,2,3,1,7]
[7,3,5,9,6,1,8,2,4]
[5,8,9,7,1,3,4,6,2]
[3,1,7,2,4,6,9,8,5]
[6,4,2,5,9,8,1,7,3]
yes
8. Derivarea
% legile derivarii pentru suma, produs,logaritm
divide10 :- d(((((((((x/x)/x)/x)/x)/x)/x)/x)/x)/x,x,_).
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/V,X,(DU*V-U*DV)/(^(V,2))) :- !,
d(U,X,DU),
d(V,X,DV).
d(^(U,N),X,DU*N*(^(U,N1))) :- !,
integer(N),
N1 is N-1,
d(U,X,DU).
d(-U,X,-DU) :- !,
d(U,X,DU).
d(exp(U),X,exp(U)*DU) :- !,
d(U,X,DU).
d(log(U),X,DU/U) :- !,
d(U,X,DU).
50
d(X,X,1) :- !.
d(_,_,0).
Apel:
?- d(^(2*x,3),x,D).
D = (0*x+2*1)*3*(2*x)^2 ?
Yes
9. Anagrame
member(X,[X|_]).
member(X,[_|T]):-member(X,T).
adaug(X,L,[X|L]).
adaug(X,[L|H],[L|R]):-adaug(X,H,R).
permut([],[]).
permut([L|H],R):-permut(H,R1),adaug(L,R1,R).
anagrame:-write('Dati un cuvant='),read(X),nl,
name(X,L),permut(L,R),
name(Cuv,R),write(Cuv),tab(5),fail.
?- anagrame.
Dati un cuvant=mere.
mere emre erme erem mree rmee reme reem mree rmee reme
reem meer emer eemr eerm meer emer eemr eerm mere emre
erme erem
no
COMENTARII - Einstein's
Riddle
51
"fish problem":
Einstein's Riddle
There are 5 houses in 5 different colors. In each house lives a man with a different
nationality. The 5 owners drink a certain type of beverage, smoke a certain brand of
cigar, and keep a certain pet. No owners have the same pet, smoke the same brand of
cigar or drink the same beverage.
Who owns the fish?
Hints:
There are five houses in five different colours starting from left to right. In each house
lives a person of a different nationality. These owners all drink a certain type of beverage,
smoke a certain brand of cigarette and keep a certain type of pet. No two owners have the
same pet, smoke the same brand or drink the same beverage. The question is: WHO
OWNS THE FISH??? Hints:
52
13. The German smokes Rothmans
14. The Norwegian lives next to the blue house
15. The person who smokes Marlboro has a neigbor who drinks water
==
% Einstein's Riddle
member(X,[X|T]).
member(X,[H|T]):-member(X,T).
iright(L, R, [L | [R | _]]).
einstein(Houses, Fish_Owner) :-
53
next_to([house, _, _, marlboro, _, _], [house, _, _, _, water, _], Houses),
For a LISP solution to the problem, and a list of links to other programs solving the
problem, see the URL http://www.weitz.de/einstein.html.
54
In the unsupercompiled program, the checkAndPrint method is evaluated at all 525=
298023223876953125 possible property assignments. When the supercompiler is applied
to Fish.java, it is this method which is significantly optimized.
class Fish {
public static final int nofHouses = 5;
public static final int nofProperties = 5;
condition9(s);
55
condition13(s);
condition4(s);
condition7(s);
condition1(s);
condition2(s);
condition3(s);
condition5(s);
condition6(s);
condition8(s);
condition14(s);
condition12(s);
condition10(s);
condition11(s);
condition15(s);
56
if (s.houses[i+1][COLORS]=="White") {
s.houses[i+1][COLORS]= "White";
return;
}}
}
throw new Exception();
}
// 7. The man living in the house right in the centre drinks milk.
// 10. The man who smokes Blend lives next to the one who keeps
cats.
// 11. The man who keeps horses lives next to the man who smokes
Dunhill.
57
inNextHouse(s, "Dunhill", "Horse");
}
// 15. The man who smokes Blend has a neighbour who drinks water
58
s.houses[i] [index(str1)]= str1;
if (s.houses[i+1][index(str2)]==str2) {
s.houses[i+1][index(str2)]= str2;
return;
}}
}
if (s.houses[i+1][index(str1)]==str1) {
s.houses[i+1][index(str1)]= str1;
if (s.houses[i] [index(str2)]==str2) {
s.houses[i] [index(str2)]= str2;
return;
}}
}
throw new Exception();
}
if(str=="Yellow" ||
str=="Blue" ||
str=="Red" ||
str=="Green" ||
str=="White" ) return COLORS;
if(str=="Dunhill" ||
str=="Blend" ||
str=="PallMall" ||
str=="Prince" ||
str=="BlueMaster" ) return CIGAR;
if(str=="Cat" ||
str=="Horse" ||
str=="Bird" ||
str=="Fish" ||
str=="Dog" ) return PET;
if(str=="Water" ||
str=="Tea" ||
str=="Milk" ||
str=="Coffee" ||
str=="Beer" ) return DRINK;
59
};
checkAndPrint (houses);
}
}
(defprolog
consistent([]).
consistent([P | Ps]) :- when((symbol? P)), !, consistent(Ps).
consistent([[~ P] | Ps]) :- when((symbol? P)), !, consistent(Ps).
append([], X, X).
append((mode [X | Y] -) W [X | Z]) :- append(Y, W, Z).
60
(defprolog
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).
member(X,[X | _]).
member(X,[_ | Z]) :- member(X,Z).
iright(L, R, [L | [R | _]]).
iright(L, R, [_ | Rest]) :- iright(L, R, Rest).")
X = german
More? (y/n) n
(defprolog
61
data(X) :- =(X,
[27,74,17,33,94,18,46,83,65,2,32,53,28,85,99,47,28,82,6,11,55,29,39,81,90,37,10
,0,66,51,7,21,85,27,31,63,75,4,95,99,11,28,61,74,18, 92,40,53,59,8]).
qsort([], R, R).
qsort([X|L], R, R0) :- partition(L, X, L1, L2), qsort(L2, R1, R0), qsort(L1, R, [X|R1]).
partition([],_,[],[]).
partition([X|L],Y,[X|L1],L2) :- when((<= X Y)), partition(L,Y,L1,L2).
partition([X|L],Y,L1,[X|L2]) :- partition(L,Y,L1,L2).")
(defprolog
"solve(ZebraColour, WaterColour) :-
constraints(Colours,Drinks,Nationalities,Cigarettes,Pets),
candidate(Colours,Drinks,Nationalities,Cigarettes,Pets),
member((h water,WaterHouse), Drinks),
member((h WaterColour,WaterHouse), Colours),
member((h zebra,ZebraHouse), Pets),
member((h ZebraColour,ZebraHouse), Colours).
62
member((h parliaments,H11), Cigarettes),
member((h kools,H12), Cigarettes),
next(H12, H13),
member((h horse,H13), Pets),
member((h coffee,H14), Drinks),
member((h green,H14), Colours),
member((h green,H15), Colours),
lleft(H16, H15),
member((h ivory,H16), Colours),
member((h milk,3), Drinks).
permutation([],[]).
permutation([A|X],Y) :- delete(A,Y,Y1), permutation(X,Y1).
delete(A,[A|X],X).
delete(A,[B|X],[B|Y]) :- delete(A,X,Y).
member(A,[A|_]).
member(A,[_|X]) :- member(A,X).
next(X,Y) :- lleft(X,Y).
next(X,Y) :- lleft(Y,X).
lleft(1,2).
lleft(2,3).
lleft(3,4).
lleft(4,5).")
Einstein's Riddle
63
> > > who hasn't resdponded ) was probably given this as a homework
> > > assignement, and is simply looking for a cheap way to get it
done.
> >
> > That'd be a very lame homework assignment. Not unless you had to
write
> > a program in $FAVOURITE_LANGUAGE to compute the answer
automatically
> > (which is much more interesting, especially if you make the program
> > start from the natural language expression of the problem! :^)
> >
> Well, try this:-)
> Written by a friend of mine. Its amazing how small can programs be if
you
> know STL. To bad I don't know stl :-)
> Of course it will need some time, as it randomly checks all
combinations...
But your program dont really do the job cos it is too slow.
You first generate the permutations and then test, the pb is that
there is too many permutations :
p[nation][english] can be either 0 1 2 3 4 or 5, same for the other
variables
you have 5*(5!) possibililty = 24 883 200 000
if you are able to do 1 000 000 ValidConstraints per second (cos you
have perhaps
a very very fast computer) you will need 24 883 seconds =~ 6hours to
compute (in the worst case
i admit)
the prolog program i propose take 0.1 second to find the solution :)
who say that prolog is slower than c++ :))
>
> George
>
> //A simple randomiser to find the solution to the riddle, by J. Y.
Goulermas
>
> #include <vector>
> #include <ctime>
> #include <algorithm>
> #include <fstream>
> #include <iomanip>
> #include <iostream>
>
> using namespace std;
>
> enum element_type { nation, colour, pet, drink, cigs
};
> enum nation_type { english, swedish, danish, german, norwegian
};
> enum colour_type { red, blue, yellow, green, white
};
> enum pet_type { cat, bird, horse, dog, fish
};
> enum drink_type { tea, water, milk, beer, coffee
};
64
> enum cigs_type { palmal, dunhill, bluemasters, prince, blends
};
>
> char* codes[][5] = { { "english", "swedish", "danish", "german",
> "norwegian" },
> { "red", "blue", "yellow", "green",
> "white" },
> { "cat", "bird", "horse", "dog",
"fish"
> },
> { "tea", "water", "milk", "beer",
> "coffee" },
> { "palmal", "dunhill", "bluemasters", "prince",
> "blends" }
> };
>
> inline bool ValidConstraints(const vector< vector<int> >& p)
> {
> return p[nation][norwegian] == 0 //Rule 9
> &&
> p[colour][blue] == 1 //Rule 14
> &&
> p[drink][milk] == 2 //Rule 8
> &&
> p[nation][english] == p[colour][red] //Rule 1
> &&
> p[nation][swedish] == p[pet][dog] //Rule 2
> &&
> p[nation][danish] == p[drink][tea] //Rule 3
> &&
> p[colour][yellow] == p[cigs][dunhill] //Rule 7
> &&
> p[pet][bird] == p[cigs][palmal] //Rule 6
> &&
> p[drink][beer] == p[cigs][bluemasters] //Rule 12
> &&
> p[nation][german] == p[cigs][prince] //Rule 13
> &&
> p[colour][green] == p[drink][coffee] //Rule 5
> &&
> abs(p[cigs][blends] - p[pet][cat]) == 1 //Rule 10
> &&
> abs(p[cigs][blends] - p[drink][water]) == 1 //Rule 15
> &&
> abs(p[pet][horse] - p[cigs][dunhill]) == 1 //Rule 11
> &&
> p[colour][green] < p[colour][white]; //Rule 4
> }
>
> void Output(const vector< vector<int> >& p,
> unsigned c
> )
> {
> ofstream text("solution.txt");
>
> for (int i = nation; i <= cigs; ++i)
> {
65
> for (int j = 0; j < p[i].size(); ++j)
> text <<setw(20)
> <<codes[i][ find(p[i].begin(), p[i].end(), j) -
p[i].begin() ];
> //get inverse permutation
> text <<endl;
> }
> text <<"\n\nTotal attempts: " <<c;
>
> text.close();
> }
>
> void main(void)
> {
> //srand( (unsigned) time(NULL) ); //optional RNG seeding
>
> int ramp[] = { 0, 1, 2, 3, 4 };
> vector< vector<int> > permutations;
> unsigned counter(0);
> for (int i = nation; i <= cigs; i++ )
> permutations.push_back( vector<int>(ramp, ramp + 5) );
>
> do
> {
> for (int i = nation; i <= cigs; i++)
> random_shuffle( permutations[i].begin(), permutations[i].end()
);
> if ( ! (++counter % 100000) )
> cout <<"\rRe-Randomisations: " <<counter;
> }
> while ( ! ValidConstraints(permutations) );
>
> Output(permutations, counter);
> }
--
Yoann Padioleau, INSA de Rennes, France,
http://www.irisa.fr/prive/padiolea
Opinions expressed here are only mine. Je n'écris qu'à titre personnel.
**____ Get Free. Be Smart. Simply use Linux and Free Software.
____**
66
and rightfully so. In fact, the part of his brain responsible for mathematical and
visual/spacial thinking was discovered to be 15% greater than the average human. In
addition, it lacked the usual groove that runs through that area, which supposedly enabled
his neurons to communicate more effectively. In other words, he's someone worth
learning from.
Over the next few weeks, I'll enter some posts highlighting his quotes as they apply to
project management. Think Einstein doesn't have anything to do with project
management? Think again. Here's the first one...
"Confusion of goals and perfection of means seems, in my opinion, to characterize our
age."
The same could be said for project management today. With all the focus on execution
and delivery, many project managers fail because they make a huge assumption that the
goals and requirements are clear. As we strive to perfect the ability to finish on-time and
on-budget, let's not forget the need to make sure that the goals of the sponsor are crystal
clear, since that's where most projects fall short.
67