this dir | view | cards | source | edit | dark
top
Neprocedurální programování
- neprocedurální jazyky nemají přiřazovací příkazy
- logické programování
- funkcionální programování
- funkce a jejich skládání
- funkce jsou „matematické“, nemají vedlejší efekty
- hlavní funktor – ten, co je nejvíc vlevo
- predikát – funkce, která odpovídá ANO/NE
- Prolog lze psát ve VS Code
- rozšíření New-VSC-Prolog
- pravé tlačítko – load document
:-
jako implikace zprava doleva
- příkaz
make.
zajistí rekompilaci
- vyhodnocení pravidla probíhá průchodem do hloubky (DFS)
- v Prologu záleží na pořadí
- středník jako OR, čárka jako AND
- konjunkce (čárka) má přednost
- operátor nerovnosti (respektive neunifikovatelnosti)
\=
- kvantifikátory se explicitně nepíšou
- pokud je proměnná jenom vpravo, je kvantifikovaná existenčně
- pokud je proměnná na obou stranách, je kvantifikovaná obecně
- s negací je obecně trochu problém
- proměnné uvozené podtržítkem a pokračující čísly používá interně Prolog (tedy je lepší, když je nepoužíváme)
- lze používat infixovou notaci
- lze přetěžovat funktory
- proměnné začínají velkým písmenem
- ukončení příkazové řádky –
halt.
- „konzultace“ (kompilace) souboru
a.pl
– consult(a).
make.
překompiluje klauzule, které se od minula změnily
muz(sokrates).
… je Sokrates muž?
- stisknutím středníku (u složeného výrazu) vynutíme selhání – Prolog zkouší další možnosti
manzele(X,Y) :- manzele(Y,X).
není správný přístup, způsobí to nekonečný cyklus
- např. dotaz
manzele(jina, karel_iv).
(kde jina
neexistuje) nikdy nedoběhne
- v případě neúspěchu se provede unifikace – ta prohodí pozice (ale to se postupně provádí donekonečna)
- …
- pracujeme s termy
- term je strukturovaný typ s více položkami
- v procedurálním jazyce by to odpovídalo typu záznam
- položky jsou identifikovány jménem
- ve složeném termu jsou položky identifikovány polohou
- fakt
- unifikace
- základní operace na termech
- unifikací
datum(D1, M1, 2024) = datum(D2, unor, R2).
je…
- D1 = D2
- M1 = unor
- R2 = 2024
- unifikaci vyvolá operátor =
- operátor
\=
vrátí true, pokud termy nelze unifikovat
guitracer.
- rekurze
predek(X,Y) :- rodic(X,Y).
predek(X,Z) :- rodic(X,Y), predek(Y,Z).
- tenhle predikát efektivně počítá potomky, ne předky
- napíšeme komentář
% predek(+Predek, ?Potomek)
- znaménko
+-
označuje, že argument může obsahovat volné proměnné
- lepší predikát
- axiomatizace přirozených čísel
- deterministická a nedeterministická implementace porovnání
- nedeterminismus jako mocný nástroj
- seznamy
- rekurze se dobře dělá tak, že řeším obecnější problém
- otáčení seznamu pomocí akumulátoru – v základním kroku (fakt) zkopíruju akumulátor do výsledné proměnné
- predikát append
- predikáty include a exclude – až příště
- programování s omezujícími podmínkami
use_module(library(clpfd)).
- obecnější aritmetické operátory, začínají znaménkem
#
- predikáty vyšších řádů
- call
- maplist
- foldl (reduce)
- seznam s volným koncem
- řez
- používat s mírou
- červený – mění deklarativní význam programu
- zelený – nemění deklarativní význam programu, pouze odřezává neperspektivní větve výpočtu
- negace
- funkcionální fronta
- Přední/Zadní
- Zadní část je otočená
- odebírám v konstantním čase ze začátku
- v konstantním čase přidávám na konec fronty (těsně za lomítko)
Haskell
- volání funkce má největší prioritu
- záporná čísla je nutné psát do závorky (opět kvůli prioritě)
- informace o funkci pomocí
:i
- z funkce můžu udělat operátor pomocí zpětných apostrofů `
- chceme mít funkce definované pro všechny hodnoty definičního oboru – proto Haskell obsahuje pouze if then else (a neobsahuje if then)
- soubor Prelude.hs obsahuje jakoby základní knihovnu
:quit
ukončí prostředí
:?
otevře nápovědu
:load soubor.hs
načte soubor
- také lze
:l
- pomocí
:r
(reload) se soubor znova načte
:type vyraz
vypíše typ výrazu
:set +t
nastavení options, např. výpis typu
:set +s
… vypíše paměť a čas