Zanke v prologu

Iz E-študij, proste zakladnice študentskega znanja

Skoči na: navigacija, iskanje

rekurzija: z avtomatskim vračanjem(findall)

Če izvedemo spodnji program, se nam zacikla. findall_napacno(X,Cilji,S) :-

 call(Cilji),
 asserta(podatek(X)),
 findall_napacno(X,Cilji,S).

Vsebina

Repeat

Repeat vedno uspe (pri avtomatskem vračanju se izvajanje vedno odbije nazaj naprej).

repeat.
repeat :- repeat.

Fail

Fail povzroči nasprotno kot repeat, izvajanje nikoli ne uspe in vedno dobimo avtomatsko vračanje.

Zato lahko enostavno povzročimo neskončno zanko:

?- repeat, fail.

Odločanje

Imamo neskončno zanko dokler ne dosežemo izstopnega pogoja (konec):

delaj_iterativno :-
  repeat,
   write(' vtipkaj ukaz: '),
   read(Ukaz),
   odloci(Ukaz).

odloci(konec).
odloci(Ukaz):-
  izvrsi(Ukaz),!,
  fail.

Fibbonacijevo zaporedje

 fib_hitri_iterat(0,1).
 fib_hitri_iterat(N,F):-
   assert(fib_st(1,1,1)), %inicializacija
   repeat,   
    retract(fib_st(Stevec,F1,F2)), % dobi
    (Stevec = N, !, F = F2; %robni pogoj
    F3 is F1 + F2,
    Stevec1 is Stevec + 1,
    assert(fib_st(Stevec1,F2,F3)), % shrani nove vrednosti
    fail).  %vse skupaj ponovi

Primeri uporabe zank

?- findall(X,otrok(X,Y),S).
S= [tine,metka,metka];
no
?- bagof(X,otrok(X,Y),S.   %setof(X,otrok(X,Y),S)
Y = tone                     %brez duplikatov
S = [tine,metka];            %sortira
Y = micka
S = [metka];
no

?- element(X,[a,b,c,d]),write(X),write(','),fail. a,b,c,d no

?- element(X,[a,b,c,d]),write(X),write(','),fail;true. a,b,c,d yes



spremeni_it(S,P,NS) :-

 findall(NX,
   (element(X,S),
    Tr =.. [P,X,NX],
    call(Tr)),
   NS).

Soda števila

soda(S,Soda) :-
  findall(X, (element(X,S),X mod 2 =:= 0), Soda).

Seznam števil na intervalu

interval(Min,Max,S) :-
  findall(X,med(Min,Max,X),S).
interval(5,10,S).
S = [6,7,8,9].

Spremeni iz seznama elementov v množico (izloči duplikate).

setof(X,element(X,[a,d,e,f,c,e,b,d]),S).
S = [a,b,c,d,e,f]
yes



Presek 2 množic

setof(X,(element(X,[a,b,e]),(element(X,[b,d,e,f])),S).
S = [b,e]
yes



Želimo imeti zanko, ki za vse X-e iz znanega seznama izvede določeno operacijo:

for_X_in_S_do_rek(_,[],_).
for_X_in_S_do_rek(X,[X|S],Cilji) :-
  call((Cilji,!,fail)).
for_X_in_S_do_rek(X,[_|S],Cilji) :-
  for_X_in_S_do_rek(X,S,Cilji).

Alternativno z uporabo element:

for_X_in_S_do_it(X,S,Cilji) :-
  element(X,S),
  call((Cilji,!,fail)).
for_X_in_S_do_it(_,_,_).
?- for_X_in_S_do_it(X,[a,b,c,d],(write(x),write(','))).
a,b,c,d,
yes
Osebna orodja
Imenski prostori
Različice
Dejanja
navigacija

Tiskanje/izvoz
orodja