Deklarativní programování

DVOP PIT


Bc. Matěj Cajthaml — SSPŠ

©

Deklarativní programování

Deklarativní programování

  • paradigma, které se snaží popsat, co má být provedeno, ne jak to má být provedeno
  • určujeme tedy výsledek, ne postup
  • výsledek je závislý na vstupu

Logické programování

  • velmi propojený s deklarativním programováním
  • základy z matematické logiky

Důvod existence

  • snaha zamezit chybám
  • chybí nutnost znát vnitřní strukturu programu
  • programátor se může soustředit na výsledek
  • programátor se nemusí starat o optimalizaci

Prolog

Prolog

  • programming in logic
  • logický programovací jazyk
  • vznikl v 70. letech 20. století
  • vývojáři: Alain Colmerauer, Robert Kowalski, Philippe Roussel
  • turingově úplný

Využití

  • umělá inteligence
  • zpracování přirozeného jazyka
  • bioinformatika

IDE a použití

  • SWI-Prolog
  • příkazová řádka

Základní pojmy

Fakta

  • výroky, které jsou považovány za pravdivé v jakémkoliv kontextu
  • v Prologu jsou fakta reprezentována jako klauzule (viz dále)

Ukázka fakt

Prozatím jsme neopužili ani jedno klíčové slovo. kocka, pes a muzeSiHratS jsou naše fakta.

Dotazy

  • na fakta a další části je možné se dotazovat
  • dotazy až po spuštění programu
  • dotazová řádka začíná většinou ?-

Ukázka dotazování

Pravidla

  • výroky, které jsou považovány za pravdivé pouze v určitých kontextech
  • v Prologu jsou pravidla reprezentována jako klauzule (viz dále)
  • přijímají jako fakta hodnoty z kterých se skládají
  • z minulého příkladu: chceme dovolit, aby jakákoliv kočka si mohla hrát s jakoukoliv kočkou

Ukázka pravidel

Syntax pravidel

  • :- něco jako if v jiných jazycích (implikace zprava doleva)
  • vlevo je hlava pravidla a musí končit tečkou
  • jednotlivé části hlavy jsou odděleny znaky:
    • , - logický součin (and, a zároveň, ...) - konjunkce
  • proměnné začínají velkým písmenem

Může existovat více pravidel pro stejné fakta. Kontrolují se v pořadí, v jakém jsou zapsána v programu.

Tranzitivní pravidla

  • pokud neumí vyřešit dotaz přímo pomocí pravidla, zkouší se pravidla tranzitivně
  • kontroluje se do té doby, než se nevyčerpají všechny možnosti
  • může způsobovat problémy (viz dále, tzv "řezy")

Ukázka tranzitivních pravidel

Dotazy s vyřešením

  • někdy nevíme, co má být výsledkem dotazu
  • můžeme nahrat parametr proměnnou
  • výsledek či výsledky se pak vypíší
  • např. muzeSiHratS(yoko, X). — vypíše všechny kočky, se kterými si může hrát Yoko
  • další výsledky pomocí středníku

Komplexní dotazy

  • stejně jako pravidla můžeme skládat dotazy pomocí logických spojek
  • např.: muzeSiHratS(yoko, X), muzeSiHratS(X, myska). — vypíše všechny věci, se kterými si může hrát yoko, a které si mohou hrát s myškou

Termíny Prologu

Termy

  • základní struktura dat v Prologu
  • dělí se na:
    • konstanty (celá čísla, reáln čísla)
    • atomy (vše, co začíná malým písmenem)
      • na více řetězce ('tohle je atom')
      • speciální symboly (;, :-, ,, ., ...)
      • seznamy ([])
    • proměnná (vše, co začíná velkým písmenem nebo podtržítkem)

Stuktury

  • skládají se z jiných termů
  • všechny prvky jsou odděleny čárkou
  • např.:
    • a(yoko)
    • b(yoko, X)
    • c(yoko, X, [A, yoko])

Klauzule

  • je buď faktem nebo pravidlem
  • fakt: jméno a argumenty
  • pravidlo: hlava a tělo

Spojky

  • , — logický součin, and
  • ; — logický součet, or, menší priorita než ,
  • :- — implikace, if
  • = — unifikace, equals
  • is — vyhodnocení aritmetiky na pravé straně a unifikace do levé
  • \= — nelze unifikovat
  • =:= — aritmetické porovnání

Prolog nemá návratové hodnoty. Jak se tedy vrací výsledek?

Unifikace

Unifikace

  • operátor =
  • jiný význam než v ostatních jazycích
  • způsobuje instanciaci proměnných, pokud je to možné
  • pokud není možné, tak se vyhodnotí jako false

Aritmetické operátory a porovnání

  • +, -, *, /
  • =, \=, <, >, <=, >=

Příklady

Předvytvořené predikáty

Výpis

  • příkaz write
  • vypíše výsledek na standardní výstup
  • příkaz nl vypíše konec řádku

Odmocnina

  • příkaz sqrt
  • příklad:
    • sqrt(4, X)

Čísla mezi

  • příkaz between
  • příklad:
    • between(1, 10, X)

Příklady

Příklady

Pro výstup používejte proměnnou X.

Násobení

Práce

Sepište program, který znásobí dvě čísla.

Mocnina 1

Práce

Sepište program, který umocní číslo na druhou.

Délka úsečky

Práce

Sepište program, který získá délku úsečky z následujícího zápisu:

delka(usecka(bod(X1, Y1), bod(X2, Y2)), D)

Mocnina 2

Práce

Sepište program, který umocní číslo na libovolnou mocninu.

Obdelník

Práce

Sepište program, který zjistí, jestli body tvoří obdelník.

jeObdelnik(bod(X1, Y1), bod(X2, Y2),
bod(X3, Y3), bod(X4, Y4))

Body postupně: levý dolní, levý horní, pravý horní, pravý dolní.

Faktoriál

Práce

Sepište program, který vypočítá faktoriál čísla $n$.

Fibonacciho posloupnost

Práce

Sepište program, který vypočítá $n$-tý člen Fibonacciho posloupnosti.

$\text{fib}(0) = 0$

$\text{fib}(1) = 1$

$\text{fib}(n) = \text{fib}(n-1) + \text{fib}(n-2)$

Listy

Listy

  • uspořádaná množina prvků
  • prvky mohou být různého typu
  • prvky jsou odděleny čárkou
  • např.: [ 1, 2, 3, [ 4, 5 ], 'a', 'b' ]

Získávání prvků

  • můžeme rozdělit na první prvky a zbytek
  • např. v argumentu a([A|T]) získáme:
    • A — první prvek
    • T — zbytek jako list

Nepojmenované parametry

  • pokud nepotřebujeme parametr, můžeme ho vynechat
  • např. v argumentu a([_|T]) získáme:
    • T — zbytek jako list

Minimum v listu

Příklady

Operace s listy

Implementujte následující operace s listy:

  • length(+List, -Length)
  • reverse(+List, -Reversed)
  • count(+List, +Element, -Count)
  • remove(+List, +Element, -Without)
  • removeAll(+List, +Element, -Without)
  • removeDuplicates(+List, -Without)
  • insert(+List, +Element, +Index, -With)
  • isSorted(+List)
  • concat(+List1, +List2, -Concat)

Seznam funkcí

Implementujte program, který získá číslo $n$ a pro něj vrátí seznam prvků $[fib(0), fib(1), \dots, fib(n)]$.

Řezy

Řezy

  • operátor !
  • zamezení zpětného návratu
  • pokud jsme našli řešení, nechceme hledat další
  • i při nalezení neúspěchu se nevracíme

Ukázka řezu

Správné minimum

Typy řezů

Práce

Zjistěte, jaký je rozdíl mezi červeným a zeleným řezem.

Negace

Práce

Napište predikát not, který bude fungovat jako negace.

Pokročilé příklady

Grafy

Graf bude reprezentován strukturou graph(Vertices, Edges), kde Edges je seznam hran ve tvaru [U, V]

Implementujte následující predikáty:

  • edge(+Graph, +U, +V) — existuje hrana mezi vrcholy U a V?
  • neighbours(+Graph, +U, -Res) — sousedé vrcholu U
  • path(+Graph, +U, +V) — existuje cesta mezi vrcholy U a V?
  • bfs a dfs — prohledávání do šířky a do hloubky*

Děkuji za pozornost!

  • matej.cajthaml@ssps.cz
  • https://ssps.cajthaml.eu/