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).
Zadnja sprememba: torek, 9. maj 2023, 12.21