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.