Laborator 3

Laborator 3

Problema 1

Cod:

abs(X, X) :- X>=0,!.

abs(X, Y) :- Y is -X.

Metoda alternativa:

abs2(X, Y) :- (X>=0, Y is X, !) ;

Y is -X.

Apel:

abs(2, Y).

abs(-2, Y).

Rezultatul obtinut:

Y = 2.

Y = 2.

Explicatii:

Daca prima conditie nu a fost valida, stim cu siguranta ca X este mai mic ca 0. In caz ca prima conditie este indeplinita, punem operatorul "cut" pentru a nu cauta si alta solutie in mod inutil.

Problema 2

Cod:

fibonacci(0, 0):-!.

fibonacci(1, 1):-!.

fibonacci(N, F) :- N>1,

Nnew is N-1,

Nnew2 is N-2,

fibonacci(Nnew, Fnew),

fibonacci(Nnew2, Fnew2),

F is Fnew+Fnew2.

Apel:

fibonacci(5, F).

Rezultatul obtinut:

F = 5.

Explicatii:

Trebuie sa punem "Nnew" si "Nnew2" din motivele precizate in lucrarea de laborator.

Problema 3

Cod:

divisor(X, Y, D) :- (Y=:=0, D is X, !) ;

Rest is X mod Y,

divisor(Y, Rest, D).

variante:

cmmdc(A, 0, D) :- D is A,!.

cmmdc(A, B, D) :- Rest is A mod B, cmmdc(B, Rest, D).

cmmdc2(A, B, D) :- (B=:=0, D is A, !);

Rest is A mod B, cmmdc2(B, Rest, D).

cmmdc3(A, A, D) :- D is A, !.

cmmdc3(A, B, D) :- A > B, Dif is A-B, cmmdc(Dif, B, D).

cmmdc3(A, B, D) :- A < B, Dif is B-A, cmmdc(A, Dif, D).

cmmdc4(A, B, D) :- (A=:=B, D is A,!);

(A > B, Dif is A-B, cmmdc(Dif, B, D));

(A < B, Dif is B-A, cmmdc(A, Dif, D)).

Apel:

divisor(15, 3, D).

Rezultatul obtinut:

D = 3.

Explicatii:

Algoritmul lui Euclid... punem operatorul "cut" pentru a stopa procesul de backtracking.

Problema 4

Cod:

evaluating(Expression, Value) :- Exp is Expression, plus(Exp, 0, Value).

eval(X, X) :- number(X).

eval(A+B, Value) :- eval(A, Anew), plus(Anew, B, Value).

eval(A-B, Value) :- eval(A, Anew), plus(B, Value, Anew).

Apel:

evaluating(1+2+3+4+5, R).

eval(1+2+3+4+5, R).

Rezultatul obtinut:

R = 15.

R = 15.

Explicatii:

Instantiez expresia si dupa o verific folosind metoda predefinita.

Sol 2:

A+B=1+2+3. =>A=1+2 si B=3.

A+B=V

Problema 5

Consider the following rules for symbolic differentiation (U, V are mathematical expressions, x is a variable):

dx/dx = 1

d(-U)/dx = -(dU/dx)

d(U+V)/dx = dU/dx + dV/dx

d(U-V)/dx = dU/dx - dV/dx

d(U*V)/dx = U*(dV/dx) + V*(dU/dx)

These rules can easily be translated into Prolog, for instance, the third rule can be defined as

diff(plus(U,V),x,plus(RU,RV)) :-

diff(U,x,RU),

diff(V,x,RV).

Write the remaining rules. Here is a test query:

?- diff(plus(times(x,x),x),x,Result).

Result = plus(plus(times(x, 1), times(x, 1)), 1) ;

No

Note: Prolog has built-in functors such as +, - and * that can be used in infix or prefix notation, so the given Prolog clause can also be written as diff(U+V,x,RU+RV):-diff(U,x,RU),diff(V,x,RV).

Keep in mind, though, that terms such as U+V are still trees with the functor at the root, and that evaluation of such terms requires additional processing (see the next question).

Write a predicate that simplifies mathematical expressions as follows:

U*1 = U

U+0 = U

U+U = 2*U

U-U = 0

Hint: most of your clauses will need to be recursive. Also add a base case that leaves the expression untouched (in case none of the cases applies), and recursive clauses that take expressions of the form U+V and return X+Y, where X is the simplification of U and Y is the simplification of V.

Here is a test query:

?- simp(plus(plus(times(x,1),times(x,1)),1),Result).

Result = plus(times(2, x), 1) ;

No

Cod:

Apel:

Rezultatul obtinut:

Explicatii: