UL/FRI/UNI-RI/MOS/Izpiti/2006-09-14-prolog
Iz E-študij, proste zakladnice študentskega znanja
|
Izpit z dne Napaka: neveljaven čas
Čas pisanja: 90 minut.
|
1. naloga
Napišite program, ki vrne seznam neznank v podanem izrazu. Na primer klic countvars(3*x*(x+2*y-(z+y)), L) vrne L = [x,y,z]. Če se ista neznanka pojavi večkrat, jo štejete samo enkrat. [25 %]'
Rešitev
countvars(X, [X]):- \+number(X), atomic(X), !. countvars(X,[]):- number(X), !. countvars(Term, L):- arg(1,Term,A), arg(2,Term,B), countvars(A, L1), countvars(B, L2), conc(L1, L2, L3), setof(X, member(X, L3), L).
2. naloga
Kako bi prologu zastavili naslednja vprašanja? [25 %]
- a) Koliko različnih elementov je v seznamu L?
- b) Koliko je 1549 * 728?
- c) Ali ne velja p(a) in hkrati velja p za kakšen element, ki ni a?
- d) Poišči seznam L, ki vsebuje vse elemente X, za katere velja ali p(X) ali q(X)!
- e) Ali obstaja kakšen element X, za katerega ne velja ne p(X) ne q(X)?
Rešitev
# a) setof(X, member(X, L), _L), length(_L, N). # b) X is 1549 * 728. # c) \+ p(a), p(A), A \== a. # d) findall(X, (p(X) ; q(X)), L). # e) \+p(X), \+q(X).
3. naloga
Kaj odgovori prolog na naslednja vprašanja? Podajte vse odgovore v pravilnem vrstnem redu! [25 %]
- a) ?- .
- b) ?- bagof(M, month(M, DaysInMonth), L). # V bazi so dejstva: month(jan, 31), month(feb, 29), ..., month(dec, 31).
- c) ?- .
- d) ?- L = [1, 2, [3, 4], 5, [[6]], 7], member(X, L), \+ number(X).
- e) ?- arg(1, conc([1,2], X, [1,2,3,4]), A).
Rešitev
# a) Syntax error # b) DaysInMonth = 29, L = [feb] ; DaysInMonth = 30, L = [apr, jun, sep, nov]; DaysInMonth = 31, L = [jan, mar, maj, jul, avg, okt, dec] ; no # c) Syntax error # d) L = [1, 2, [3, 4], 5, [[6]], 7], X = [3, 4]; L = [1, 2, [3, 4], 5, [[6]], 7], X = [[6]]; no # e) A = [1, 2]; no
4. naloga
Napišite predikat, ki iz danega seznama števil naredi in vrne dva seznama, v enem so liha, v drugem pa soda števila. Obenem poskrbi, da se duplikati izločijo. Primer: separate([2,4,1,5,2,7,7], L, S) vrne L = [1,5,7] in S = [2,4]. [25%]
Rešitev
separate([], [], []). separate([H|T], L, S):- 0 is (H mod 2), %gre za sodo stevilo separate(T, L, S1), \+member(H, S1), %odpravimo podvajanja S = [H|S1], !. separate([H|T], L, S):- 1 is (H mod 2), %gre za liho stevilo separate(T, L1, S), \+member(H, L1), %odpravimo podvajanja L = [H|L1], !. separate([_|T], L, S):- separate(T, L, S).
ali
separate(T, L, S) :- setof(X, (member(X, T), X mod 2 =:= 1), L), setof(X, (member(X, T), X mod 2 =:= 0), S).
Ker v običajnem prologu ni na voljo funkcija mod, je potrebno zadevo sam sprogramirati
liha(1):-!. liha(X):- X>0, X1 is X-2,liha(X1). soda(2):-!. soda(X):- X>0, X1 is X-2,soda(X1). separate(Seznam,L,S):- setof(X,(member(X,Seznam),liha(X)),L), setof(X,(member(X,Seznam),soda(X)),S).
Od kod informacija, da mod ni na voljo?