====== Prolog ======
[[wp>Prolog]]
===== Principy =====
**Programy jsou ze 2 častí:**
  * Vlastní program – Hornovy klauzule, které tvoří hypotetický základ pro důkaz.
  * Dotazy – cíle, predikáty, které chceme z dané hypotézy ověřit, zda platí nebo ne
**Hornovy klauzule sa vyskytují ve 2 variantách:**
  * Fakta – např. ''ditetem(andulka, jan)''.
  * Plné klauzule s hlavou a tělem (pravidlo) – např. ''vnukem(X,Y) :- ditetem(X,Z), ditetem(Z,Y)''.
**Struktura**
  * Termy – konstanty, proměnné, struktury
  * Klauzule
  * Cíle
===== Vyhodnocování =====
  * Vyhodnocování se provádí na základě [[wp>SLD resolution|SLD rezoluce]] – podcíle jsou expandované do hloubky.
  * Podcíle jsou v klauzili vyhodnocované zleva doprava.
  * Snaha unifikovat podcíl s hlavičkou faktu (klazule vložené do programu), potom je tělo této nalezené klauzule vyhodnocované zleva doprava a každý atom na pravé straně je zpracován do hloubky.
  * Při selhání se vykonává návrat (backtracking).
===== Unifikace =====
Robinsonův unifikační algoritmus
  * Nevykonáva se kontrola výskytu (neodhalí sa např. ''X = f(X)'', což můze vést na nekonečný výsledný term)v
  * Základní a jediná operácia v Prologuv
  * Využití:
    * Přiřazení (navázání) hodnoty k nějaké proměnné: ''proměnná = hodnota''.
    * Test na rovnost (unifikovatelnost) termů (i složitějších struktur): ''term1 == term2''
    * Výběr ze seznamu: ''L = [X|_]''
    * Vytváření struktur: ''Y = [a, b, c]''
    * Předávání parametru hodnotou (term je předaný jako skutečný argument)
    * Předávání parametru odkazem (proměnná je odevzdána jako skutečný argument)
    * Sdílení proměnných a vytváření synonym: ''a(P, Q) -> a(X, X)''
===== Vestavěné predikáty =====
  * Vetšinou nejsou znovuspustitelné
  * Nevyhnutelné pro praktické programování
  * Aritmetické operace pomocí ''is''
  * Testování typu – ''integer(X)'', ''atom(X)'' (''X'' je identifik8tor, konstanta)
  * Metalogické – test, zdaje proměnná navázaná ...
  * Operace s klauzulemi – dynamické přídávání (''assert'') a odebírání (''retract'') klauzulí
===== Operátor řezu =====
[[wp>Cut (logic programming)]]
  * Predikát, který uspěje právě jednou.
  * Pokud se program při backtrackingu dostane k operátoru řezu, selže celý podcíl a všechny body znovuuspění mezi hlavičkou kaluzule a operátorem řezu jsou zapomenuty.
**Správné použití:**
  * chceme Prologu říct, že už se našlo hledané řešení a nemá cenu hledat dále (koncová podmínka): sum_to(1, 1) :- !.
sum_to(N, Res) :- N1 is N - 1, sum_to(N1, Res1), Res is Res1 + N.
  * Bylo dosaženo stavu který už nevede k řešení – checeme aby podcíl selhal: not(P) :- call(P), !, fail.
not(P).
  * Ukončení generování alternativních řešení: is_integer(0).
is_integer(X) :- is_integer(Y), X is Y + 1.
divide(N1, N2, Result) :- is_integer(Result), Product1 is Result * N2, Product2 is (Result + 1) * N2, Product1 =< N1, Product2 > N1, !.
**Nesprávné použití:**
  * Nesprávné použití může zamezit nelezení všech výsledků nebo nalezené chybných výsledků!
  * S operátorem řezu mají predikáty silně vymezený charakter podle toho u kterých parametrů můžou mít volnou proměnnou a kde je třeba mít hodnotu.