Kapitola 4: Anatomie proměnné – Java vs. Python vs. Prolog

Vítejte zpět v detektivní kanceláři Prologu! V minulé kapitole jsme se naučili, jak Prologu "říct", co je pravda, pomocí atomů a faktů. Ale co když nevíme, co přesně hledáme? Co když chceme říct "NĚKDO" nebo "NĚCO"? Představte si, že jste Sherlock Holmes a potřebujete se zeptat: "Kdo je otcem Barta?" nebo "Co má rád Homer?". K tomu slouží proměnné – naše klíčové nástroje pro kladení otázek a hledání odpovědí.

Ale pozor! Pokud už máte zkušenosti s programováním v jazycích jako Java nebo Python, připravte se na další "kulturní šok". Proměnná v Prologu funguje úplně jinak. Mnoho studentů zde dělá chybu, protože si myslí, že proměnná je všude stejná. Není. Pochopení tohoto rozdílu je naprosto klíčové pro to, abyste Prologu skutečně porozuměli.

4.1 Java: Proměnná jako pevná krabice (Statická typizace)

V jazyce Java (nebo C++) si proměnnou můžete představit jako **pevně danou krabici**. Musíte předem říct, co v krabici bude a jaký má typ. Je to jako krabice s nápisem "POUZE CELÁ ČÍSLA".

int x = 5;

Říkáte: "Vytvoř krabici jménem X. Tato krabice je vyrobena z kovu a vejdou se do ní POUZE celá čísla. Teď tam dej pětku." Pokud tam zkusíte dát text "Ahoj", program spadne. Krabice má pevný tvar a obsah můžete měnit (dát tam 6), ale typ ne. Je to jako mít krabici na jablka – nemůžete do ní dát hrušky, aniž byste ji změnili.

4.2 Python: Proměnná jako nálepka (Dynamická typizace)

V Pythonu je to volnější. Proměnná není krabice, ale spíše **nálepka nebo ukazatel**. Můžete ji kdykoli přilepit na jinou věc.

x = 5
x = "Ahoj"

Říkáte: "Nalep nálepku se jménem X na číslo 5." Pak můžete nálepku strhnout a nalepit ji na text "Ahoj". Proměnná je jen odkaz, který se může měnit a ukazovat na cokoliv. Je to jako mít nálepku "Moje oblíbená věc" a přelepovat ji z jablka na hrušku.

4.3 Prolog: Proměnná jako neznámá (Logická proměnná)

V Prologu je to úplně jinak. Proměnná v Prologu (vždy začíná Velkým písmenem, např. X, Kdo, Vysledek) je jako **prázdná skleněná krabice s jmenovkou, která se po prvním naplnění zalepí**. Na začátku je prázdná (neinstanciovaná) – představuje neznámou, kterou hledáme.

PROMĚNNÁ V PROLOGU Symbol, který začíná velkým písmenem (nebo podtržítkem), a reprezentuje neznámou hodnotu, kterou Prolog hledá.

Jakmile Prolog najde hodnotu, která "pasuje" (pomocí procesu zvaného unifikace, o kterém si povíme za chvíli), tato hodnota se do proměnné "vloží". A teď to nejdůležitější: krabice se **zalepí**. Už to **nemůžete vyměnit** v rámci jednoho dotazu nebo pravidla. Tomu se říká **Jednorázové přiřazení (Single Assignment)**. Nemůžete říct X = 5 a na dalším řádku X = 6. To by byla logická lež, protože X nemůže být zároveň 5 i 6.

JEDNORÁZOVÉ PŘIŘAZENÍ (SINGLE ASSIGNMENT) Princip v Prologu, kdy proměnná může být instanciována (získat hodnotu) pouze jednou v rámci jednoho vyhodnocení dotazu nebo pravidla. Jakmile je hodnota přiřazena, nelze ji změnit.
Srovnání proměnných
Obrázek 4.1: Rozdíl mezi proměnnými v Javě (krabice), Pythonu (nálepka) a Prologu (jednorázová schránka).

4.4 Viditelnost proměnné (Rozsah platnosti)

Toto je další velmi důležitý rozdíl! Proměnná v Prologu existuje **pouze uvnitř jednoho pravidla** (nebo jednoho dotazu). Není globální. Představte si to jako jména studentů v různých třídách. Student "Petr" v 1.A nemá nic společného se studentem "Petr" v 2.B, i když se jmenují stejně.

ROZSAH PLATNOSTI (SCOPE) Oblast kódu, ve které je proměnná platná a má svůj význam. V Prologu je rozsah platnosti proměnné omezen na jedno pravidlo nebo dotaz.
otec(X, Y) :- rodic(X, Y), muz(X).
deda(X, Y) :- otec(X, Z), rodic(Z, Y).

Proměnná X v pravidle otec nemá NIC společného s proměnnou X v pravidle deda. Jsou to dvě různé "krabice", které se náhodou jmenují stejně. Jakmile Prolog dokončí práci s pravidlem, "krabice" se zahodí a její obsah se zapomene.

4.5 Anonymní proměnná (_) – Když nás detaily nezajímají

Někdy nás hodnota proměnné nezajímá. Chceme jen vědět, jestli "někdo" nebo "něco" existuje, ale je nám jedno kdo nebo co. K tomu slouží **anonymní proměnná**, která se značí podtržítkem _.

ANONYMNÍ PROMĚNNÁ (_) Speciální proměnná v Prologu, která slouží jako zástupný symbol pro jakoukoli hodnotu, jejíž konkrétní obsah nás nezajímá. Každý výskyt _ je považován za jinou proměnnou.

?- rodic(homer, _).

Tím říkáme: "Je Homer rodičem *někoho*?" Je nám jedno koho. Prolog odpoví true, pokud najde alespoň jedno dítě. Nezatěžuje paměť ukládáním jména dítěte, protože jsme mu řekli, že nás to nezajímá. Je to jako když se ptáte: "Je tu *někdo* doma?", a ne "Kdo je doma?".

4.6 Unifikace (Zázrak spojení) – Jak Prolog hledá pravdu

Když napíšeme X = karel, Prolog neprovádí "přiřazení" jako v matematice (že by do X uložil hodnotu). On provádí **unifikaci**. Unifikace je srdcem Prologu. Je to proces, kdy Prolog se snaží, aby dvě věci (termy) byly stejné, a pokud to jde, najde hodnoty pro proměnné, které to umožní.

UNIFIKACE Základní mechanismus Prologu, který se snaží najít takové hodnoty pro proměnné, aby se dva termy staly identickými. Pokud je to možné, proměnné se instanciují (získají hodnotu). Pokud ne, unifikace selže.

Představte si unifikaci jako **detektiva, který hledá shodu**. Máte dva otisky prstů a detektiv se snaží najít, zda patří stejné osobě, a pokud ano, kdo to je.

Řešené příklady: Ptáme se našeho detektiva

Příklad 4.1: Dotaz s proměnnou

Máme fakta:

rodic(homer, bart).
rodic(homer, lisa).
rodic(marge, bart).
rodic(marge, lisa).

A teď se zeptáme našeho Prolog detektiva:

?- rodic(homer, X).

Co se ptáme: "Kdo je dítětem Homera?"

Jak Prolog "myslí":

  1. Prolog se podívá do své databáze. Hledá fakt, který pasuje na vzor rodic(homer, NĚCO).
  2. Najde první shodu: rodic(homer, bart).
  3. Vidí, že homer sedí. A vidí, že na místě X je bart.
  4. Provede unifikaci: X = bart.
  5. Odpoví vám: X = bart.

Pokud stisknete středník (;), řeknete Prologu: "Dobře, to je jedna odpověď, ale existuje ještě nějaká?"

  1. Prolog se vrátí a hledá další shodu pro rodic(homer, NĚCO).
  2. Najde rodic(homer, lisa).
  3. Provede unifikaci: X = lisa.
  4. Odpoví vám: X = lisa.

Pokud stisknete středník znovu, Prolog už další shody nenajde a odpoví false.

Klíčový koncept: Proměnné jako "otazníky"

V Prologu proměnné nejsou místa pro ukládání hodnot, které se mění. Jsou to spíše "otazníky" ve vašich dotazech a pravidlech. Prolog se snaží najít takové hodnoty pro tyto otazníky, aby celé tvrzení bylo pravdivé. Tento proces hledání shody a přiřazování hodnot se nazývá unifikace a je základem veškerého logického odvozování v Prologu.

Otázky k zamyšlení

  1. Představte si, že jste učitel a máte seznam studentů. Jak byste vysvětlili rozdíl mezi proměnnou v Pythonu a proměnnou v Prologu svému studentovi? Použijte analogii s jmény na seznamu.
  2. Proč v Prologu nemůžeme napsat X = X + 1? Co by to znamenalo z pohledu logiky a unifikace?
  3. Kdy byste použili anonymní proměnnou _? Vymyslete si vlastní příklad z běžného života nebo hry.
  4. Vysvětlete, co se stane, když se Prolog pokusí unifikovat barva(cervena) = barva(modra). Proč to selže?

🧪 Laboratoř: Unifikační hádanky