Prolog
-=-=-=-=
The connection between the language in which we think/program and the problems
and solutions we can imagine is very close. For this reason restricting
language features with the intent of eliminating programmer errors is at best
dangerous.
- Bjarne Stroustrup in "The C++ Programming Language"
Prolog vychází z logického kalulu. Podporuje jenom spojku & a
definování predikátů, ale to úplně stačí. Má algoritmus, který sám
najde řešení pro napsanou formuli.
Každý program se zkládá ze dvou částí - popisu světa a dotazů.
Definice světa - tedy predikátů se zkládá z několika řádek
ve formátu:
predikat(parametry).
Každému takovému zápisu se říká term. Prolog si je uloží do své
databáze. Například mu tam můžu uložit rubriky výhně:
rubrika(uvodnik).
rubrika(software).
rubrika(freesoft).
rubrika(demo).
rubrika(hudba).
rubrika(nazory).
rubrika(pocitac).
rubrika(tvorivost).
rubrika(konecnik).
Nyní prolog ví, že existuje predikát rubrika s jedním
parametrem, který je 1 pro parametry uvodnik, software, freesoft
atd. Můžu uložit i některé články, které jsem do výhně napsal spolu
s rubrikou a číslem vydání:
clanek(gnu,software,7).
clanek(gcc,freesoft,8).
clanek(cotoje,freesoft,8).
clanek(x11,freesoft,8).
clanek(cm,pocitac,9).
clanek(lisp,software,9).
clanek(prolog,software,9).
Vlastní prolog funguje vpodstatě jako chytrá databáze. Můžu
vznášet různé dotazy na svět, který jsem mu popsal. Například pokud
se chci zeptat, jestli existuje rubrika pocitac, napíšu:
?- rubrika(pocitac).
Yes
?- je prompt a prolog odpověděl na můj dotaz Yes. Tedy,
že predikát je pravdivý. Pokud naopak chci zjistit, jaké existují
rubriky napíšu:
?- rubrika(X).
X = uvodnik
X je volná proměná (proměné se poznají podle velkého písmena,
nebo _ na začátku). Proměné v prologu fungují trochu jinak, než
proměné v procedurálních jazycích. Zde zatím prolog nezná hodnotu
proměné X a proto může nabývat libovolné hodnoty. Prolog prohledal
svoji databázi a našel první možnost - uvodnik a nabízí mi ji. Teď
můžu zmáčknout enter, a ukončit vyhledávání, nebo středník a najít
další možnost:
?- rubrika(pocitac).
Yes
4 ?- rubrika(X).
X = uvodnik ;
X = software ;
X = freesoft ;
X = demo ;
X = hudba ;
X = nazory ;
X = pocitac ;
X = tvorivost ;
X = konecnik ;
No
Tady jsem nebyl spokojen ani z jednou odpovědí a prolog tedy
vyhledával další a další možnosti až nakonec nic nového nenašel
a odpovědel No.
Pokud potřebuju vědět v jakém čísle byl vydán článek x11,
napíšu:
?- clanek(x11,X,Y).
Y = 8
X = freesoft ;
A prolog vyhledá číslo i rubriku. Pokud mě rubrika nezajímá,
můžu použít anonymní proměnou _:
?- clanek(x11,_,Y).
Y = 8
Nejzajímavější ale je, že můžu definovat nové predikáty nejen
výčtem, ale také pomocí dotazů. Například můžu napsat predikát,
který zjistí, jestli jsem do dané rubriky v daném čísle něco napsal.
Můžu do definice světa přidat:
rubrika(Rubrika,Cislo) :- rubrika(Rubrika),clanek(_,Rubrika,Cislo).
Operátor :- je vlastně obrácená implikace a čárka znamena AND.
Celé to tedy říká, že pokud je Rubrika rubrikou a existuje nějaký
článek (_) z rubriky Rubrika v číle číslo, je rubrika neprázdná.
Toto je definice predikátu rubrika se dvěma parametry. Ten nemá
nic společného z predikátem rubrika s jedním parametrem, který je
použit pro výčet rubrik.
Nyní tento nový predikát můžu použít pro zjištění seznamu všech
neprázdných rubrik v jednotlivých číslech:
?- rubrika(X,Y).
Y = 7
X = software ;
Y = 9
X = software ;
Y = 9
X = software ;
Y = 8
X = freesoft ;
Y = 8
X = freesoft ;
Y = 8
X = freesoft ;
Y = 9
X = pocitac ;
Výpisy se opakují, protože pokaždé se pro dočasnou proměnou
z jménem článku použl jiný článek. Může také zjistit, jaké rubriky
byly v čísle 8:
?- rubrika(X,8).
X = freesoft ;
X = freesoft ;
X = freesoft ;
O jiné rubrice, než freesoft neví. Nebo se můžu naopak ptát,
ve kterých číslech byla rubrika freesoft:
?- rubrika(freesoft,X).
X = 8 ;
X = 8 ;
X = 8 ;
Jak vidíte každý predikát lze použít mnoha způsoby. Pokud máte
predikát na sčítání, máte vlastně i predikát na odčítání a dělení
na dva díly apod. Prostě predikáty v prologu jsou mnohem obecnější,
než funkce ve strukturovaných jazycích.
výheň