![]() |
![]() |
Osnova
- Cyklus řízený neúspěchem
- Modifikace interní databáze
- Množinové predikáty (All solutions)
- NEW stránka s řešením
- Cyklus řízený neúspěchem
může mít tyto formy:a) uzivatelsky_generator_i_nekonecny ... uzivatelsky_test b) repeat, i_o_predikat ... uzivatelsky_test c) uzivatelsky_generator_konecny ... failKdyž uživatelský test neuspěje, cyklus pokračuje, když uspějě, cyklus končí. Pokud uživatelský test nikdy neuspějě a generátor je nekonečný, bude i cyklus nekonečný. Uvnitř cyklu využíváme predikáty s vedlejším efektem (napr. I/O - vstup/výstup), protože hodnoty proměnných se po neúspěchu zapomenou.
priklad_b:- repeat, read(X), zpracuj(X), X=konec. zpracuj(_).- Modifikace interní databáze, predikáty assert/1, retract/2
Tyto predikáty používáme pouze v omezené míře, protože narušují logické čtení programu, zejména bychom neměli modifikovat predikáty zevnitř (v jejich těle). Nejvhodnější použití je například přidání již odvozeného tvrzení (efektivita), uchování málo používaných "globálních" proměnných a pod.
Přidání již odvozeného tvrzení, tzv. lemma/1:
lemma(P):-call(P),asserta((P:-!)).Je nutné přidávat na začátek predikátu (asserta/1) a odvození odříznout řezem.Příklad použití lemma/1:
:-op(500,xfx,'=>'). % definice infixoveho operatoru - sipka :- dynamic hanoi1/5. % deklarace dynamickeho predikatu hanoi1/5 hanoi(N,A,B,C,R):-hanoi1(N,A1,B1,C1,R-[]),A1=A,B1=B,C1=C. hanoi1(1,A,B,C,[A=>B|R]-R). hanoi1(N,A,B,C,R0-R):-N>1, N1 is N-1, hanoi1(N1,A,C,B,R0-R1), asserta((hanoi1(N1,A,C,B,R0-R1):-!)), R1=[A=>B|R2], hanoi1(N1,C,B,A,R2-R).- dotaz
- Proč není predikát hanoi/5 definován následujícím způsobem?
hanoi(N,A,B,C,R):-hanoi1(N,A,B,C,R-[]).- Množinové predikáty (All-solutions)
- Napište program, který najde seznam všech detí daného nebo libovolného otce collect(Father,Kids) s využitím nasledující databáze:
father(petr,petra). father(petr,pavla). father(pavel,jana). father(pavel,jan).
^