Lab2 example solution (doesn't include bonus).

This commit is contained in:
Peter 2023-08-11 02:20:07 +08:00
parent 10237b7386
commit 76d2e91d4d

View File

@ -0,0 +1,95 @@
% Lab 2 - Recursive Arithmetic in Prolog
% LABSHEET:
% https://teaching.csse.uwa.edu.au/units/CITS3005/labs/lab02-arithmetic.pdf
% Build a Prolog program to do recursive arithmetic. It should have
% 1. a constant, zero, to represent zero.
zero.
% 2. a function, next(X), that represents the next number (so next(zero) represents one).
next(X) :- X.
% 3. a predicate, sum(X,Y,Z), which is true if X + Y = Z.
% sum(zero,zero,Z) :- Z is zero.
% sum(zero,Y,Z) :- Z is Y.
% sum(next(zero),Y,Z) :- Z is next(Y).
sum(zero,zero,zero). % CASE 1 : 0 + 0 == 0
sum(zero,X,X). % CASE 2 : 0 + X == X
sum(next(X),Y,next(Z)) :- sum(X,Y,Z). % CASE 3 : (X+1) + Y == (Z+1) (Works based on previous two cases???)
% TEST 1:
% sum(next(zero),next(zero),next(next(zero)))
%=sum(zero,next(zero),next(zero)) [ TRUE ]
% TEST 2:
% sum(next(next(zero)),zero,next(zero))
%=sum(next(zero),zero,zero) [ FALSE ]
% 4. a predicate, mult(X,Y,Z) which is true if X × Y = Z.
mult(zero,zero,zero).
mult(zero,_,zero).
mult(next(zero),X,X).
mult(next(X),Y,Z) :- mult(X,Y,Zp), sum(Y,Zp,Z). % (x+1)*y == x*y+y
% 5. a predicate, equals(X,Y) which is true if X = Y .
equals(X,X).
% 6. a predicate, lessThan(X,Y) which is true if X < Y ¿
lessThan(zero,next(_)).
lessThan(next(X),next(Y)) :- lessThan(X,Y). % X+1 < Y+1 => X < Y. As X->0, Y->N => 0 < N.
% binary_(zero,0).
% binary_(next(X),IntValue) :- binary_(X,PrevIntValue), write(PrevIntValue), IntValue is PrevIntValue+1.
% binary(X) :- binary_(X,Buffer), write(Buffer).
% Test your program and consider the efficinecy of the implementations. Is there a way to get faster annswers?
% Next, add additional functions:
% 1. Write a program binary(X) that will print the binary representation of X out, so for example, binary(next(next(zero)
% will print out 10.
% NOTE: Binary array is in reverse!
increment_b([],[]).
increment_b([ODigit | ORest],[Digit | Rest]) :-
ODigit =:= 0 -> Digit is 1,
equals(Rest,ORest);
ODigit =:= 1 -> Digit is 0,
(
equals(ORest,[]) -> equals(Rest,[1]);
increment_b(ORest,Rest)
).
% NOTE: Binary array is in reverse!
binary_arr(zero,[0]).
binary_arr(next(X),NextBinary) :-
binary_arr(X,Binary),
increment_b(Binary,NextBinary).
binary_arr_print([]).
binary_arr_print([Digit|Rest]) :- write(Digit), binary_arr_print(Rest).
binary(X) :-
binary_arr(X,BinaryArrRev),
reverse(BinaryArrRev, BinaryArr),
binary_arr_print(BinaryArr).
% 2. Implement predicates for odd, even and prime numbers.
even(zero).
even(next(X)) :- \+even(X).
odd(X) :- \+even(X).
% Cheating a bit here ... would be harder doing the whole primality test in the above notation, since I don't have a modulo predicate defined
to_integer(zero,0).
to_integer(next(X),Integer) :- to_integer(X,OInteger), Integer is OInteger + 1.
not_prime_i(I,Comp) :-
Comp*Comp < I+1,
(I mod Comp =:= 0; I mod (Comp + 2) =:= 0;
not_prime_i(I,Comp+6)).
prime_i_entry(I) :-
I > 1, (I =:= 2; I =:= 3;
I mod 2 =\= 0, I mod 3 =\= 0,
\+not_prime_i(I, 5)).
prime(X) :- to_integer(X,I), prime_i_entry(I).