Logično programiranje
Naloga: nakupi
Dano je zaporedje prologovih stavkov o nakupih:
bought(eva, bread, 1). % Eva je kupila 1 kg kruha
bought(tomi, beer, 6). % Tomi je kupil 6 litrov piva
bought(eva, butter, 2). % Eva je kupila tudi 2 kg jabolk
bought(tina, beer, 2).
bought(tina, salami, 1).
price(beer, 2). % liter piva stane 2 €
price(apples, 1). % kg jabolk pa 1 €
price(bread, 3).
price(salami, 17).
- Za gornjo bazo nakupov podaj vse prologove odgovore na vprašanje:
?- bought(X, beer, Qty), price(beer, P), Value #= Qty * P.
- Zapiši vprašanje za prolog, ki poišče osebo X, ki je kupila vsaj dva različna proizvoda.
Rešitev
- Odgovori na vprašanje:
?- bought(X, beer, Qty), price(beer, P), Value #= Qty * P.
X = tomi, Qty = 6, P = 1.9, Value = 12 ;
X = tina, Qty = 2, P = 1.9, Value = 4.
- Oseba, ki je kupila vsaj dva različna proizvoda:
?- bought(X, P, _), bought(X, R, _), P \== R.
Naloga: vsi enaki
Definiraj predikat all_equal(L)
, ki uspe, če so v seznamu L
vsi elementi enaki. Primer:
?- all_equal([a,a,a,a]).
true.
?- all_equal([a,b,c,a]).
false.
?- all_equal([a,X,Y,a,a]).
X = a, Y = a.
Rešitev
all_equal([]).
all_equal([_]).
all_equal([H,H|T]) :-
all_equal([H|T]).
Naloga: telefon
Na telefonski številčnici pišemo besede tako, da za vsako črko nekajkrat pritisnemo ustrezno številko. Tipke, ki jih moramo pritisniti za posamezne črke, so podane s predikatom letter/2
:
letter(a, [2]). % za črko 'a' moramo enkrat pritisniti 2
letter(b, [2,2]). % za črko 'b' moramo dvakrat pritisniti 2
… %
letter(t, [8]). % številčnica (za tiste s pametnimi telefoni):
letter(u, [8,8]). %
letter(v, [8,8,8]). % 1 2 abc 3 def
… % 4 ghi 5 jkl 6 mno
letter(z, [9,9,9,9]). % 7 pqrs 8 tuv 9 wxyz
Napiši predikat spell/2, ki za dan seznam črk vrne zaporedje (seznam) tipk, ki jih moramo pritisniti za zapis teh črk. Primer:
?- spell([a,v,t,o], L).
L = [2,8,8,8,8,6,6,6].
Rešitev
spell([], []).
spell([H|T], L) :-
letter(H, Hs),
spell(T, LT),
append(Hs, LT, L).
Naloga: črkovanje
Podana sta predikata letter/1
in word/1
, ki vračata veljavne črke oziroma besede v jeziku. Posamezna beseda je predstavljena kot seznam črk. Primer:
letter(L) :-
member(L, [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]).
word([c,h,a,i,r]). word([c,h,e,s,s]). word([d,e,s,k]).
word([c,h,a,l,k]). word([c,h,o,p]). word([d,i,s,k]).
Napiši predikat edit(Word, New)
, ki vhodno besedo Word
»popravi« v besedo New
na enega od treh načinov: izbriše poljubno črko, vstavi novo črko na poljubno mesto, ali pa eno črko na poljubnem mestu zamenja z novo. Predikat naj generira vse možne rešitve.
Primer uporabe:
?- edit([i,t], New).
New = [t] ; % izbrisana črka
…
New = [a,i,t] ; % vstavljena črka
…
New = [i,j,t] ; % vstavljena črka
…
New = [a,t] ; % zamenjana črka
…
Rešitev
edit(Word, New) :-
insert(_, New, Word).
edit(Word, New) :-
letter(L),
insert(L, Word, New).
edit(Word, New) :-
letter(L),
append(A, [_|B], Word),
append(A, [L|B], New).