Doposud jsme pracovali se seznamy, které jsou jako dlouhá nitka korálků. Ale svět není plochý. Svět je 3D prostor, hierarchie a vztahy. Soubory ve vašem počítači jsou organizovány ve stromech (složky ve složkách). Rodokmeny jsou stromy. Hry se odehrávají v prostoru se souřadnicemi. Prolog umí tyto složité struktury reprezentovat velmi elegantně a přirozeně.
Vektory nebo body v prostoru v Prologu reprezentujeme pomocí struktur. Už jsme se s nimi setkali
(např. kniha(...)). Teď je použijeme pro geometrii. Bod ve 2D prostoru můžeme zapsat jako
bod(X, Y).
Příklad: Je úsečka vodorovná?
Úsečka je definována dvěma body. Je vodorovná, pokud mají oba body stejnou souřadnici Y.
% usecka(Bod1, Bod2)
vodorovna(usecka(bod(X1, Y), bod(X2, Y))).
Všimněte si kouzla unifikace. Použili jsme proměnnou Y na obou místech. Tím jsme
Prologu řekli: "Nezajímá mě, jaká je to hodnota, ale musí být na obou místech stejná."
?- vodorovna(usecka(bod(1, 5), bod(10, 5))). -> true (Y je 5).?- vodorovna(usecka(bod(1, 5), bod(10, 6))). -> false (5 není 6).Stromy jsou základem efektivního vyhledávání. Představte si Binární vyhledávací strom (BST). Má jeden kořen a dvě větve. Pravidlo je jednoduché: Všechno, co je menší než kořen, jde doleva. Všechno, co je větší, jde doprava.
V Prologu strom zapíšeme jako strukturu: strom(Hodnota, LevyPodstrom, PravyPodstrom). Prázdný strom
(list) označíme jako nil.
% Strom z obrázku:
strom(5,
strom(3, nil, nil), % Vlevo je 3
strom(8, nil, nil) % Vpravo je 8
).
Příklad 13.1: Hledání v BST
Díky pravidlu "menší vlevo, větší vpravo" najdeme cokoliv bleskově rychle. Nemusíme prohledávat celý strom, v
každém kroku zahodíme polovinu možností!
% 1. Našli jsme to! Hodnota v uzlu je to, co hledáme.
najdi(X, strom(X, _, _)).
% 2. Hledané X je menší než kořen -> Jdi doleva.
najdi(X, strom(Koren, Levy, _)) :-
X < Koren,
najdi(X, Levy).
% 3. Hledané X je větší než kořen -> Jdi doprava.
najdi(X, strom(Koren, _, Pravy)) :-
X > Koren,
najdi(X, Pravy).
Prolog je geniální v tom, jak umí rozebrat složité struktury přímo v hlavičce pravidla. Místo abychom psali
"Vezmi první argument, zkontroluj jestli je to bod...", prostě napíšeme vzor bod(X, Y) a Prolog
se postará o zbytek. Tomu se říká Pattern Matching.
(2 + 3) * 4? (Kořen je násobení,
vlevo je sčítání...).t(a, t(b, nil, nil), t(c, nil, nil)).
uvnitr(Bod, Obdelnik), který zjistí,
zda je bod uvnitř obdélníku. Obdélník definujte dvěma body (levý dolní a pravý horní).
Bod(X,Y) je uvnitř, pokud X je mezi X1 a
X2 A ZÁROVEŇ Y je mezi Y1 a Y2.
pocet_uzlu(Strom, N), který
spočítá, kolik má strom uzlů.
nil je 0.