\(\newenvironment{bprooftree}{\begin{prooftree}}{\end{prooftree}}\)
15 Jun 2026

Teorija programskih jezikov (Pretnar)

Lecture 1: Praksa programskih jezikov

Razlika med tem kako je jezik implementiran in kako je standardiziran.

Sintaksa in semantika

Sintaksa opisuje kako napišemo programe. Semantika opisuje kaj pomenijo.

Konkretna in abstraktna sintaksa

Konkretna sintaksa: zaporedja črk, ki jih zapišemo (besedilo). Abstraktna sintaksa: syntax trees (AST - abstract syntax tree).

Semantiko lahko podajamo na različne načine.

  • Specificirano z implementacijo
  • Specificirano s prozo
  • Specificirano z matematičnimi simboli
  • Specificirano z matematičnimi objekti (denotacijska semantika)
Faze urejevalnika
  1. Razčlenjevalnik (Parser): Prevodba iz konkretne sintakse v abstraktno sintakso (AST)
  2. Obogatitev drevesa: Preverjanje tipov, optimizacija, ipd.
  3. Interpreter/Compiler: Tolmačimo ali prevedemo v drug jezik/strojno kodo
Jezik Imp

Najpreprostejši učni jezik za definicijo semantike.

Implementirali smo type checker.

Lecture 2: Indukcija

Podatkovne tipe specificiramo z indukcijo.

\(\N\) je definirana kot najmanjša množica, kjer je

  • \(0 \in \N\)
  • \(n \in \N \implies n^{ + } \in \N\)

To zapišemo tudi s pravili izpeljave:

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(0 \in \N\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(n \in \N\)} \UnaryInfC{\(n^{ + } \in \N\)} \end{bprooftree} \end{gather*}

Aritmetične izraze lahko podamo kot \[ e ::= \underline{n} \mid -e \mid e_1 + e_2 \mid e_1 * e_2, \] ali s pravili izpeljave:

\begin{gather*} \begin{bprooftree} \AxiomC{\(n \in \Z\)} \UnaryInfC{\(\underline{n} \in \mathbb{E}\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(e \in \mathbb{E}\)} \UnaryInfC{\(-e \in \mathbb{E}\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(e_1 \in \mathbb{E}\)} \AxiomC{\(e_2 \in \mathbb{E}\)} \BinaryInfC{\(e_1 + e_2 \in \mathbb{E}\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(e_1 \in \mathbb{E}\)} \AxiomC{\(e_2 \in \mathbb{E}\)} \BinaryInfC{\(e_1 * e_2 \in \mathbb{E}\)} \end{bprooftree} \end{gather*}

Z drevesom izpeljave lahko ekonomično pišemo dokaze vsebovanosti.

Induktivna definicija sodosti naravnih števil:

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(0\) je sodo} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(n\) je sodo} \UnaryInfC{\(n^{ ++ }\) je sodo} \end{bprooftree} \end{gather*}

Induktivna definicija relacije manjšega ali enakosti:

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(n \leq n\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(m \leq n\)} \UnaryInfC{\(m \leq n^{ + }\)} \end{bprooftree} \end{gather*}

Alternativna (ekvivalentna) definicija:

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(0 \leq n\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(m \leq n\)} \UnaryInfC{\(m^{ + } \leq n^{ + }\)} \end{bprooftree} \end{gather*}

Obe definiciji podata ekvivalentno relacijo.

Induktivno relacijo \(R \subseteq X\) lahko predstavimo z družino induktivnih množic \((D_x)_{x \in X}\), kjer \(D_x\) predstavlja množico dokazov, da je \(x \in R\).

Obratno, iz vsake družine \((D_x)_{x \in X}\) lahko definiramo relacijo \(R \subseteq X\) kot \[ R = \left\{ x \in X \mid D_x \neq \emptyset \right\}. \]

Definirajmo družino \((S_n)_{n \in \N}\) s pravili

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\text{NicSodo} \in S_{0}\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(d \in S_n\)} \UnaryInfC{\(\text{NaslNaslSodo } d \in S_{n^{ ++ }}\)} \end{bprooftree} \end{gather*}

Elementi \(S_n\) so dokazni drevesi, da je \(n\) sodo.

Pri aritmetičnih izrazih:

  • Ker imamo konstante, moramo imeti vsaj \(I_0 = \{\underline{n} \mid n \in \Z\}\)
  • Zaradi pravila \(\operatorname{Plus}\) imamo tudi \((\underline{0} + \underline{0}) \in I_1\), podobno za \(\operatorname{Krat}\) in \(\operatorname{Minus}\)
  • Iz teh dobimo dodatne elemente, kot so \(((\underline{0} + \underline{0}) * \underline{0}) \in I_2\)

Ideja je, da na vsakem koraku iz do sedaj zgrajenih elementov \(I_n\) dobimo množico \(I_{n+1}\). To konstrukcijo bomo opisali s funktorjem.

Funktor za naravna števila

Naravna števila predstavimo s funktorjem \[ FX = 1 + X \]

Tu \(X\) predstavlja že sestavljene elemente. Iterirana aplikacija predstavlja dodajanje vseh novih izrazov na danem koraku:

  • \(I_0 = \emptyset\)
  • \(I_1 = 1 + \emptyset = \{\iota_0(\cdot)\}\)
  • \(I_2 = 1 + I_1 = \{\iota_0(\cdot), \iota_1(\iota_0(\cdot))\}\)
  • \(I_3 = 1 + I_2 = \{\iota_0(\cdot), \iota_1(\iota_0(\cdot)), \iota_1(\iota_1(\iota_0(\cdot)))\}\)

In tako dalje. Pišemo \(\iota_0(\cdot) = 0\) in \(n^{ + } = \iota_1(n)\).

Aritmetične izraze predstavimo s funktorjem \[ FX = \Z + X + 2X^2 \]

kjer \(\Z\) predstavlja konstante, \(X\) unarni operatorji in \(2X^2\) binarni operatorji.

Naj bo \(F\) funktor, ki je monoton in Scottovo zvezen. Potem ima \(F\) najmanjšo fiksno točko, ki jo označimo z \(\mu F\).

Monotonost: \(X \subseteq Y \implies FX \subseteq FY\)

Scottova zveznost: \[ F\left(\bigcup_{i=1}^{\infty} X_i\right) = \bigcup_{i=1}^{\infty} FX_i \]

Najmanjša fiksna točka je \[ \mu F = \bigcup_{i=1}^{\infty} F^i \emptyset \]

To je najmanjša množica, zaprta za \(F\): \[ FX \subseteq X \implies \mu F \subseteq X \]

Opomba: Potenčna množica ni Scottovo zvezna.

Pišimo \(I_0 = \emptyset\) in \(I_{n+1} = FI_n\) ter \(I = \bigcup_{i=1}^{\infty} I_i\).

Najprej pokažimo, da je \(\mu F\) fiksna točka.

\textit{(1) \(I \subseteq FI\)):}

Imamo \(I_0 = \emptyset \subseteq I_1\), zato je po monotonosti tudi \(I_1 = F\emptyset \subseteq FI_1 = I_2\), in tako dalje. Zato \(I_n \subseteq FI_n\) za vsak \(n\). Potem je \[ I = \bigcup_j I_j \subseteq \bigcup_j FI_j \subseteq FI. \]

Zadnja inkluzija velja, ker je \(I_j \subseteq I\) za vsak \(j\), zato je \(FI_j \subseteq FI\) po monotonosti, torej tudi \(\bigcup_j FI_j \subseteq FI\).

\textit{(2) \(FI \subseteq I\)):}

Naj bo \(x \in FI\). Po definiciji \(x\) nastane iz končno mnogo elementov \(I_k\) za neki fiksni \(k\). Zato je \(x \in FI_k = I_{k+1} \subseteq I\). Torej \(FI \subseteq I\).

\textit{(3) Minimalnost:} Če je \(FX \subseteq X\), je \(I \subseteq X\).

Imamo \(\emptyset \subseteq X\). Ker je \(F\emptyset \subseteq FX \subseteq X\), je \(I_1 \subseteq X\). Induktivno, če je \(I_j \subseteq X\), je \(I_{j+1} = FI_j \subseteq FX \subseteq X\). Zato je \[ I = \bigcup_{j=1}^{\infty} I_j \subseteq X. \]

Lecture 3: Indukcija 2

Lastnost \(\mu F\) lahko uporabimo za dokazovanje z indukcijo.

Naj bo \(P \subseteq \mu F\) zaprta za \(F\), torej \(FP \subseteq P\). Po izreku sledi \(P = \mu F\).

\(P \subseteq \N\) naj bo nek predikat na \(\N\), zaprt za \(F : X \rightarrow 1 + X\). Razpišim \(FP \subseteq P\).

\begin{align*} FP &\subseteq P \\ n \in FP &\implies n \in P \\ n \in 1 + P &\implies n \in P \\ n = \iota_0( * ) \lor \exists m \in P . \, n \iota_1(n) & \implies n \in P \end{align*}

To pomeni, da imamo \[ 0 \in P \lor \forall m \in \N \implies m \in P \implies m^{ + } \in P \] Rekonstruirali smo načelo indukcije za naravna števila.

Konstrukcija primitivne rekurzije

S pomočjo funktorja \(F\) lahko izrazimo tudi primitivno rekurzivne funkcije na \(\mu F\).

Recimo, za \(\operatorname{ev} : \mathbb{E} \rightarrow \Z\) imamo

\begin{align*} \operatorname{ev}(\underline{n}) &= n \operatorname{ev}(e_1 + e_2) &= \operatorname{ev}(e_1) + \operatorname{ev}(e_2) \operatorname{ev}(e_1 * e_2) &= \operatorname{ev}(e_1) \cdot \operatorname{ev}(e_2) \operatorname{ev}(-e) &= -\operatorname{ev}(e) \end{align*}

NB primitivno rekurzivna funkcija je podana že s štirimi funkcijami:

\begin{align*} \alpha_{1} &: \N \rightarrow \Z \alpha_{2} &: \Z \times \Z \rightarrow \Z \alpha_{3} &: \Z\times \Z\rightarrow \Z \alpha_{4} &: \Z \rightarrow \Z \end{align*}

kar lahko predstavimo ravno s preslikavo \[ \alpha : \N + \Z \times \Z + \Z \times \Z + \Z \rightarrow \Z. \] To je ravno \(F\Z\). To je algebra za funktor \(F\).

Algebra za funktor \(F\) je

  • Množica \(X\)
  • Preslikava \(\alpha : FX \rightarrow X\)

Homomorfizem algebr je homomorfizm algebr.

Trditev: Obstoj začetne algebre.

Algebra \((\mu F, \operatorname{id} : \mu F = F \mu F \rightarrow F \mu F)\) je začetna algebra za \(F\). Za poljubno algebro \(X, \alpha\) obstaja enoličen homomorfizem \(\alpha : \mu F \rightarrow X\).

Lecture 3: Metateorija programskih jezikov

Sintaksa jezika Imp

Za množico lokacij \(l \in \mathbb{L}\) definiramo sinkakso jezika

\begin{align*} e &::= \underline{n} \mid e_1 + e_2 \mid e_1 * e_2 \mid -e \mid l \\ b &::= \texttt{true} \mid \texttt{false} \mid e_1 < e_2 \mid e_1 = e_2 \mid e_1 > e_2 \\ c &::= \text{skip} \mid c_1 ; c_2 \mid \text{if } b \text{ then } c_1 \text{ else } c_2 \mid l := e \mid \text{while } b \text{ do } c \end{align*}

Semantiko izrazov bomo podali operacijsko – prek relacij, ki bodo opisale korake računanja. Imamo dve različici.

  • Mali koraki: \((2 + 4) * 7 \rightsquigarrow 6 * 7 \rightsquigarrow 42\)
  • Veliki koraki: \((2 + 4) * 7\ \rightsquigarrow 42)

Imp - Semantika

Semantika jezika Imp

Naj bo \(\mathbb{S} = \Z_{\bot}^{\mathbb{L}}\) množica stanj pomnilnika. Evaluacijo aritmetičnih izrazov podamo z relacijo \(s, e \Downarrow n \subseteq \mathbb{S} \times \mathbb{E} \times \Z\).

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(S, \underline{n} \Downarrow n\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(S, e_1 \Downarrow n_1\)} \AxiomC{\(S, e_2 \Downarrow n_2\)} \BinaryInfC{\(S, e_1 + e_2 \Downarrow n_1 + n_2\)} \end{bprooftree} \qquad \begin{bprooftree} \AxiomC{\(S, e_1 \Downarrow n_1\)} \AxiomC{\(S, e_2 \Downarrow n_2\)} \BinaryInfC{\(S, e_1 * e_2 \Downarrow n_1 \cdot n_2\)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(S, e \Downarrow n\)} \UnaryInfC{\(S, -e \Downarrow -n\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(s(l) \neq \bot\)} \UnaryInfC{\(s, l \Downarrow s(l)\) } \end{bprooftree} \end{gather*}

Za logične izraze imamo relacijo \(s, b \Downarrow r \in \mathbb{B} = \left\{ \mathit{tt}, \mathit{ff} \right\}\)

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(S, \texttt{true} \Downarrow \mathit{tt} \)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(S, \texttt{false} \Downarrow \mathit{ff} \)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(S, e_1 \Downarrow n_1\)} \AxiomC{\(S, e_2 \Downarrow n_2\)} \AxiomC{\(n_1 < n_2\)} \TrinaryInfC{\(S, e_1 < e_2 \Downarrow \mathit{tt}\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(S, e_1 \Downarrow n_1\)} \AxiomC{\(S, e_2 \Downarrow n_2\)} \AxiomC{\(n_1 \geq n_2\)} \TrinaryInfC{\(S, e_1 < e_2 \Downarrow \mathit{ff}\)} \end{bprooftree} \end{gather*}

in podobno za ostale.

\begin{prooftree} \AxiomC{\(S, c_1 \leadsto S', c_1'\)} \UnaryInfC{\(S, (c_1 ; c_2) \leadsto S', (c_1', c_2)\)} \end{prooftree} \begin{prooftree} \AxiomC{\(\)} \UnaryInfC{\(S, (\text{skip} ; c_2) \leadsto S, c_2\)} \end{prooftree} \begin{prooftree} \AxiomC{\(S, b \Downarrow \mathit{tt}\)} \UnaryInfC{\(S,\ \text{if } b \text{ then } c_1 \text{ else } c_2 \leadsto S, c_1\)} \end{prooftree}

Podobno za \(\mathit{ff}\) in \(c_2\).

\begin{prooftree} \AxiomC{\(S, e \Downarrow n\)} \UnaryInfC{\(S, l := e \leadsto S[l \mapsto n], \text{ skip}\)} \end{prooftree} \begin{prooftree} \AxiomC{\(S, b \Downarrow \mathit{ff}\)} \UnaryInfC{\(S, \text{ while } b \text{ do } c \leadsto S, \text{ skip}\)} \end{prooftree} \begin{prooftree} \AxiomC{\(S, b \Downarrow \mathit{tt}\)} \UnaryInfC{\(S, \text{ while } b \text{ do } c \leadsto S, (c ; \text{ while } b \text{ do } c)\)} \end{prooftree}

Da izključimo možnost neveljavnega branja iz pomnilnika, podajmo relacije za preverjanje veljavnosti. Z \(L\) označimo množice lokacij. Pišemo \(L \vdash e\) ko je \(e\) veljavna za veljavne lokacije \(L\).

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(L \vdash \underline{n}\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(L \vdash e_1\)} \AxiomC{\(L \vdash e_2\)} \BinaryInfC{\(L \vdash e_1 + e_2\)} \end{bprooftree} \quad \text{ podobno za ostale operacije. } \\ \begin{bprooftree} \AxiomC{\(l \in L\)} \UnaryInfC{\(L \vdash l\) } \end{bprooftree} \end{gather*}

Podobno za \(L \vdash b\). Moramo še podati pravila oblike \(L \vdash c, L'\).

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(L \vdash \text{ skip}, L\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(L \vdash c_1, L'\)} \AxiomC{\(L' \vdash c_2, L''\)} \BinaryInfC{\(L \vdash (c_1 ; c_2), L''\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(L \vdash b\)} \AxiomC{\(L \vdash c_1, L_1\)} \AxiomC{\(L \vdash c_2, L_2\)} \TrinaryInfC{\(L \vdash \text{ if } b \text{ then } c_1 \text{ else } c_2, L_1 \cap L_2\)} \end{bprooftree} \text{ lahko bi vzeli tudi samo } L \text{ (lokalni bind)} \\ \begin{bprooftree} \AxiomC{\(L \vdash b\)} \AxiomC{\(L \vdash c, L'\)} \BinaryInfC{\(L \vdash \text{ while } b \text{ do } c, L\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(L \vdash e\)} \UnaryInfC{\(L \vdash l := e, L \cup \left\{ l \right\}\) } \end{bprooftree} \end{gather*}

S tem lahko končno podamo netrivialno drevo izpeljave.

\begin{prooftree} \AxiomC{} \UnaryInfC{\(S, \underline{3} \Downarrow 3\)} \AxiomC{\(S(a) = 10 \neq \bot\)} \UnaryInfC{\(S, a \Downarrow 10\)} \AxiomC{} \UnaryInfC{\(S, b \Downarrow 4\)} \BinaryInfC{\(S, a + b \Downarrow 14\)} \BinaryInfC{\(S, \underline{3} * (a + b) \Downarrow 42\)} \end{prooftree}
Napredek

Naj bo \(L \subseteq \left\{ l \mid S(l) \neq \bot \right\}\) in naj velja \(L \vdash c, L'\).

Tedaj velja:

  • Bodisi \(c = \text{skip}\)
  • Bodisi obstajata \(s', c'\), da velja \(s, c \leadsto s', c'\)

Z indukcijo na \(L \vdash c, L'\) na drevo izpeljave.

Recimo, da je zadnje uporabljeno pravilo:

\begin{prooftree} \AxiomC{} \UnaryInfC{\(L \vdash \text{skip, } L\) } \end{prooftree}

Potem velja \(c = \) skip.

Za

\begin{prooftree} \AxiomC{\(L \vdash c_1, L'\)} \AxiomC{\(L' \vdash c_2, L''\)} \BinaryInfC{\(L \vdash (c_1 ; c_2), L''\)} \end{prooftree}

po indukcijski predpostavki za \(L \vdash c_1, L'\) velja

  1. bodisi \(c_1 = \) skip, zato \(s, (\text{skip} ; c_2) \leadsto s, c_2\).
  2. bodisi \(s, c_1 \leadsto s', c_1'\), zato \(s, (c_1 ; c_2) \leadsto s', (c_1'; c_2)\).

in tako dalje.

Ohranitev

Naj velja \(L \vdash c, L'\) in \(s, c \leadsto s', c' za nek \(L \subseteq \left\{ l \mid s(l) \neq \bot \right\} \).

Tedaj velja tudi \(L'' \vdash c', L'\) za nek \(L \subseteq L''\), da velja \[ L'' \subseteq \left\{ l \mid s'(l) \neq \bot \right\}. \]

Če imamo \(\underbrace{\emptyset}_{L} \vdash (l := 3, m := 4), \underbrace{\left\{ l, m \right\}}_{L'}\) je potem \(L'' = \left\{ l \right\}\).

Lecture 4: Lambda račun

Rekurzivna definicija fakultete

Želimo definirati \(\operatorname{fact} = \lambda n . \text{if } n = 0 \text{ then } 1 \text{ else } n \cdot \operatorname{fact}(n - 1)\). Znamo zakodirati vse razen ciklične definicije \(\operatorname{fact}\). Da se tej definiciji izognemo, to najprej naredimo za vezano spremenljivko. Definiramo \[ \Phi = \lambda f . \, \dots f \dots \] ki vzame funkcijo in jo aplicira v sebi. Poiščemo fiksno točko \(\Phi\).

Recimo, če vzamemo konstanto \(f_0 = \lambda x .\, 42\) dobimo \(f_1 = \Phi f_0\), ki deluje po korakih.

  0 1 2 3 4 5 6
\(f_0\) 42 42 42 42 42 42 42
\(f_1 = \Phi f_1\) 1 42 84 126      
\(f_2 = \Phi f_1\) 1 1 84 252      
\(f_3 = \Phi f_2\) 1 1 2 6      

Ko gremo naprej dobimo funkcijo vedno bolj podobno fakulteti. Za začetno funkcijo najraje uporabimo nekaj nikjer definiranega. Hkrati imamo operatorja

\begin{align*} \Omega &= (\lambda x . xx) (\lambda x . xx) \\ Y' &= \lambda \Phi . (\lambda f .ff)(\lambda f. \Phi(ff)) \\ Y' \Phi_K &\leadsto (\lambda f. ff)(\lambda f. \Phi_k(ff)) \\ &\leadsto (\lambda f . \Phi_K(ff))(\lambda f. \Phi_K(ff)) \\ &\leadsto \Phi_K\left( (\lambda f. \Phi_k(ff))(\lambda f. \Phi_k(ff)) \right) \end{align*}

kjer \(Y'\) na specifičnem \(\Phi_K\) deluje tako, da spredaj dodaja \(\Phi_K\).

Potem vzamemo \[ Y = \lambda \Phi . (\lambda f.ff)(\lambda f.\lambda x . (\Phi(f f)) x) \]

(Better check the online notes for more detail etc).

Lecture 5: Lambda račun s preprostimi tipi

i.e. simply-typed \(\lambda\)-calculus (STLC).

STLC \begin{align*} M, N &::= x \mid \lambda x . M \mid M N \mid \\ & \underline{n} \mid \operatorname{isZero} M \mid M + N \mid M * N \mid M - N \mid \cdots \\ & \texttt{true} \mid \texttt{false} \mid \text{if } M \text{ then } N_1 \text{ else } N_2 \\ A, B ::= \text{int} \mid \text{bool} \mid A \rightarrow B \end{align*}

Kjer imamo izraze in njihove tipe. Podajmo semantiko. Vrednosti so \[ V ::= \lambda x . M \mid \underline{n} \mid \texttt{true} \mid \texttt{false} \]

\begin{gather*} \begin{bprooftree} \AxiomC{\(M \leadsto M'\)} \UnaryInfC{\(MN \leadsto M'N\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(N \leadsto N'\)} \UnaryInfC{\(VN \leadsto VN'\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\lambda x. M\) V \leadsto M[V/x] } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(M \leadsto M'\)} \UnaryInfC{\(\operatorname{isZero} M \leadsto \operatorname{isZero} M'\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{isZero} 0 \leadsto \texttt{true}\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(n \neq 0\)} \UnaryInfC{\(\operatorname{isZero} \underline{n} \leadsto \texttt{false}\) } \end{bprooftree} \end{gather*}

Podobni pravili imamo še za if then else in ostalo. To poda operacijsko semantiko malih korakov.

Dodamo še relacijo tipov \(\Gamma \vdash M : A\). Te dodajo sintaktična pravila

\begin{gather*} \begin{bprooftree} \AxiomC{\((x : A) \in \Gamma\)} \RightLabel{var} \UnaryInfC{\(\Gamma \vdash x : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma, x : A \vdash M : B\)} \RightLabel{lam} \UnaryInfC{\(\Gamma \vdash \lambda x . M : A \rightarrow B\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A \rightarrow B\)} \AxiomC{\(\Gamma \vdash N : A\)} \RightLabel{app} \BinaryInfC{\(\Gamma \vdash MN : B\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{} \RightLabel{const} \UnaryInfC{\(\Gamma \vdash \underline{n} : \operatorname{int}\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : \operatorname{int}\)} \RightLabel{isZero} \UnaryInfC{\(\Gamma \vdash \operatorname{isZero} M : \operatorname{bool}\) } \end{bprooftree} \cdots \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : \operatorname{bool}\)} \AxiomC{\(\Gamma \vdash N_1 : A\)} \AxiomC{\(\Gamma \vdash N_2 : A\)} \RightLabel{if} \TrinaryInfC{\(\Gamma \vdash \text{if } M \text{ then } N_1 \text{ else } N_2 : A\)} \end{bprooftree} \end{gather*}
\begin{prooftree} \AxiomC{} \UnaryInfC{\(x : \operatorname{int}\vdash x : \operatorname{int}\) } \AxiomC{} \UnaryInfC{\(x : \operatorname{int} \vdash \underline{3} : \operatorname{int}\) } \BinaryInfC{\(x : \operatorname{int} \vdash x + \underline{3} : \operatorname{int}\) } \UnaryInfC{\(x : \operatorname{int} \vdash \operatorname{isZero}(x + \underline{3}) : \operatorname{bool}\) } \UnaryInfC{\(\vdash \lambda x . \operatorname{isZero}(x + \underline{3}) : \operatorname{int} \rightarrow \operatorname{bool}\) } \end{prooftree}
Napredek

Če velja \(\vdash M : A\), tedaj

  1. Bodisi je \(M\) vrednost,
  2. Bodisi obstaja \(M'\), da je \(M \leadsto M'\).

Z indukcijo na drevo izpeljave \(\vdash M : A\). Obravnavajmo zadnje uporabljeno pravilo.

  • Če je zadnje pravilo var ne pride v poštev, ker je kontekst prazen.
  • Za lam velja, ker že imamo vrednost.
  • Če imamo

    \begin{prooftree} \AxiomC{\(\vdash M' : A' \rightarrow A' \)} \AxiomC{\(\vdash N : A'\)} \BinaryInfC{\(\vdash M' N : A\) } \end{prooftree}

    po indukcijski predpostavki velja napredek za \(\vdash M' : A' \rightarrow A\). Če je \(M'\) vrednost, hitro vidimo, da je oblike \(\lambda x . M''\). Poleg tega ga po indukcijski predpostavki velja napredek za \(\vdash N : A'\). Če je \(N\) vrednost \(V\), je \(M'N = (\lambda x . M'') V\), zato lahko naredimo korak

    \begin{prooftree} \AxiomC{} \UnaryInfC{\((\lambda x . M'') V \leadsto M''[V/x]\) } \end{prooftree}

    Po drugi strani, če obstaja \(N'\), da je \(N \leadsto N'\), pa velja

    \begin{prooftree} \AxiomC{\(N \leadsto N'\)} \UnaryInfC{\((\lambda x . M'') N\leadsto (\lambda x . M'') N'\) } \end{prooftree}

    Če po drugi strani \(M'\) naredi korak \(M' \leadsto M''\), tedaj velja

    \begin{prooftree} \AxiomC{\(M' \leadsto M''\)} \UnaryInfC{\(M' N \leadsto M'' N\) } \end{prooftree}
  • Za const smo končali.
  • Za isZero moramo po indukciji za \(M\).
  • Za if moramo po indukciji za bool.

Ostalo podobno.

(o substituciji)

Če velja \(\Gamma, x : A \vdash M : B\) in \(\Gamma \vdash N : A\), tedaj velja \(\Gamma \vdash M[N/x] : B\)

Vaja.

Ohranitev

Če velja \(\vdash M : A\) in \(M \leadsto M'\), tedaj velja tudi \(\vdash M' : A\).

Z indukcijo na \(M \leadsto M'\).

  1. Recimo, da imamo

    \begin{prooftree} \AxiomC{\(M' \leadsto M''\)} \UnaryInfC{\(M' N\ \leadsto M'' N) } \end{prooftree}

    Potem iz \(\vdash M' N : A\) sledi \(\vdash M' : A' \rightarrow A\) in \(\vdash N : A'\) za nek \(A'\). Po indukcijski predpostavki velja \(\vdash M'' : A' \rightarrow A\), zato velja

    \begin{prooftree} \AxiomC{\(\vdash M'' : A' \rightarrow A\)} \AxiomC{\(\vdash N : A'\)} \BinaryInfC{\(\vdash M'' N : A\)} \end{prooftree}
  2. Za

    \begin{prooftree} \AxiomC{\(N \leadsto N'\)} \UnaryInfC{\(VN \leadsto VN'\) } \end{prooftree}

    postopamo podobno.

  3. \((\lambda x . M') V \leadsto M'[V/x]\) velja \(\vdash \lambda x . M' : A' \rightarrow A\) in \(\vdash V : A'\), zato tudi \(x : A' \vdash M' : A\) in po lemi o substituciji velja \(M'[V/x] : A\).
Izrek o varnosti

Če velja \(\vdash M : A\), tedaj:

  • bodisi obstaja vrednost \(\vdash V : A\), da je \(M = V\)
  • bodisi obstaja \(\vdash M' : A\), da je \(M \leadsto M'\).
Normalizacija

Če velja \(\vdash M : A\), tedaj obstaja \(\vdash V : A\), da je \[ M \leadsto^{ * } V \]

To je zato, ker v jeziku ni rekurzije.

Na izpitu 31. 1. 2020.

Ne obstaja tip \(A\), da bi veljalo \[ \vdash \Omega : A. \]

Rekurzijo moramo dotati eksplicitno.

\begin{align*} M, N &::= \cdots \mid \mathtt{rec} f \,x .\, M \\ V &::= \cdots \mid \mathtt{rec} f\, x.\, M \end{align*} \begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\((\mathtt{rec} f\, x.\, M)V \leadsto M[ \mathtt{rec} f\,x.\, M/f, V/x ] \) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma, f : A \rightarrow B\)} \AxiomC{\(x : A, \Gamma \vdash M : B\)} \BinaryInfC{\(\Gamma \vdash \mathtt{rec} f\, x.\, M : A \rightarrow B\) } \end{bprooftree} \end{gather*}

Preverimo lahko, da varnost še velja, normalizacija pa ne.

Lecture 6: Dokazovalniki

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \AxiomC{\(\Gamma \vdash N : B\)} \BinaryInfC{\(\Gamma \vdash \left< M, N \right> : A \times B\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A \times B\)} \UnaryInfC{\(\Gamma \vdash \operatorname{fst} M : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A \times B\)} \UnaryInfC{\(\Gamma \vdash \operatorname{snd} M : B\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \UnaryInfC{\(\Gamma \vdash \iota_0 M : A + B\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : B\)} \UnaryInfC{\(\Gamma \vdash \iota_1 M : A + B\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A + B\)} \AxiomC{\(\Gamma, x : B \vdash N_1 : C\)} \AxiomC{\(\Gamma, y : B \vdash N_2 : C\)} \TrinaryInfC{\(\Gamma \vdash \text{match } M \text{ with } \iota_1 x \rightarrow N_1 \mid \iota_1 x \rightarrow N_1\)} \end{bprooftree} \end{gather*}

Imamo tudi druga pravila za tipiziranje lambde, specifično unit in empty type

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\Gamma \vdash \left< \right> : 1\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : \emptyset\)} \UnaryInfC{\(\Gamma \vdash \text{absurd } M : C\) } \end{bprooftree} \end{gather*}

Naravna dedukcija za izjavni račun poda še en primer induktivno podane relacije. \[ P, Q, R ::= P \Rightarrow Q \mid \top \mid P \land Q \mid \bot \mid P \lor Q. \] Uporabljamo zapis \(\Phi \vdash P\) ki za dane predpostavke izpelje \(P\).

\begin{gather*} \begin{bprooftree} \AxiomC{\(P \in \Phi\)} \UnaryInfC{\(Q \vdash P\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi, P \vdash Q\)} \UnaryInfC{\(\Phi \vdash P \Rightarrow Q\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash P \Rightarrow Q\)} \AxiomC{\(\Phi \vdash P\)} \BinaryInfC{\(\Phi \vdash Q\)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\Phi \vdash \top\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash P\)} \AxiomC{\(\Phi \vdash Q\)} \BinaryInfC{\(\Phi \vdash P \land Q\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash P \land Q\)} \UnaryInfC{\(\Phi \vdash P\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Phi \vdash P \land Q\)} \UnaryInfC{\(\Phi \vdash Q\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash \bot\)} \UnaryInfC{\(\Phi \vdash P\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash P\)} \UnaryInfC{\(\Phi \vdash P \lor Q\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Phi \vdash Q\)} \UnaryInfC{\(\Phi \vdash P \lor Q\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Phi \vdash P \lor Q\)} \AxiomC{\(\Phi, P \vdash R\)} \AxiomC{\(\Phi, Q \vdash R\)} \TrinaryInfC{\(\Phi \vdash R\)} \end{bprooftree} \end{gather*}

S tem podamo intuicionistično logiko. Če dodamo LEM, dobimo klasično logiko.

Opazimo, da so pravila analogna pravilom za tipizacijo. \(\Phi \vdash P\) velja natanko tedaj, ko obstaja \(M\), da velja \[ \Gamma \vdash M : A \] za ustrezna \(\Gamma\) in \(A\).

Gre za konkreten primer Curry-Howardovega izomorfizma.

Teorija tipov Logika
tip izjava
izraz dokaz
\(\rightarrow\) \(\Rightarrow\)
1 \(\top\)
\(\times\) \(\land\)
\(\emptyset\) \(\bot\)
\(+\) \(\lor\)
družina tipov \(\{A(X)\}_{x \in X}\) Predikat \(P(x)\)
\(\prod(x : X) .\,A(x)\) \(\forall\)
\(\sum(x : X) . \, A(x)\) \(\exists\)
   

NB produktni tip si predstavljamo kot odvisno funkcijo \((x : X) \rightarrow A(x))\). Odvisno vsoto včasih pišemo tudi \[ \sum(x : X) . \, A(x) = \coprod_{x \in X}A(x)= (x : X) \times A(x) \] kjer zadnji zapis res eksplicitno pokaže dejstvo, da imamo odvisne pare.

(Lecture 7): Denotacijska semantika

Zakaj bi sploh imeli denotacijsko semantiko?

Izraza \[ \lambda x.\, x * 2 \text{ in } \lambda x.\, 2 * x \] nista enaka, želeli pa bi, da sta. Enaka sta na način da se pri vsakem vhodu evaluirata v isti izhod.

\noindent To nas motivira, da uvedemo kontekstno ekvivalenco.

Izraza \(M\) in \(N\) sta kontekstno ekvivalentna in pišemo \(M \simeq N \) če za vsak kontekst \(\mathcal{C}\) (izraz z luknjo) veja \[ \mathcal{C}[M] \leadsto^{ * } \mathtt{true} \iff \mathcal{C}[N] \leadsto^{ * } \mathtt{true} \]

\(\mathcal{C}\) formalno definiramo kot \[ \mathcal{C} ::= [~] \mid \underline{n} \mid \mathcal{C}_1 + \mathcal{C}_2 \mid \mathcal{C}_1 * \mathcal{C}_2 \mid \mathtt{true} \mid \mathtt{false} \mid \lambda x.\, \mathcal{C} \mid \cdots \]

Definiramo še \(\mathcal{C}(M)\) kot izraz, ki ga dobimo, če v \(\mathcal{C}\) vse \([~]\) zamenjamo z \(M\).

\[ \mathcal{C} := \lambda x .\, (1 + [~] * x) \]

\(M \simeq N\) velja natanko tedaj, ko za vsak \(\mathcal{C}\) velja \[ \mathcal{C}[M] \leadsto^{ * } \mathtt{false} \iff \mathcal{C}[N] \leadsto^{ * } \mathtt{false} \]

Predpostavimo \(M \simeq N\) in dokažimo \[ \forall \mathcal{C} .\, \mathcal{C}[M] \leadsto^{ * } \mathtt{false} \iff \mathcal{C}[N] \leadsto^{ * } \mathtt{false}. \] Vzemimo \(\mathcal{C}\) in predpostavko \(\mathcal{C}[M] \leadsto^{ * } \mathtt{false}\). Naj bo \[ \mathcal{C}' = \text{if } \mathcal{C} \text{ then } \mathtt{false} \text{ else } \mathtt{true} \] zato velja \[ C'[M] \leadsto^{ * } \text{ if } \mathtt{false} \text{ then } \mathtt{false} \text{ else} \mathtt{true} \leadsto \mathtt{true}. \] Ker je \(M \simeq N\), velja tudi \(\mathcal{C}'[N] \leadsto^{ * } \mathtt{true}\). Zato mora veljati \(\mathcal{C}[N] \leadsto^{ * } \mathtt{ false}\).

Implikacija v drugo smer poteka enako.

\noheading Podobno lahko pokažemo da je \[ M \simeq N \iff \left( \forall \mathcal{C} .\, \mathcal{C}[M] \leadsto^{ * } \underline{n} \leadsto \mathcal{C}[N] \leadsto^{ * } \underline{n}\right) \] ali celo \[ M \simeq N \iff \left( \forall \mathcal{C} .\, \mathcal{C}[M] \text{ konvergira} \iff \mathcal{C}[N] \text{ konvergira} \right). \]

Kontekstna ekvivalenca je zelo močno orodje, vendar je zelo težko kvantificirati čez vse kontekste.

\[ M \simeq N \centernot\iff \left( \forall \mathcal{C} .\, \mathcal{C}[M] \leadsto^{ * } V \iff \mathcal{C}[N] \leadsto^{ * } V \right) \]

Naivna interpretacija

Vsakemu tipu \(A\) bomo priredili množico \(\llbracket A \rrbracket\), ki ji pravimo interpretacija \(A\).

\begin{align*} \llbracket \mathtt{bool}\rrbracket &= \mathbf{B} = \left\{ \mathsf{tt}, \mathsf{ff} \right\} \\ \llbracket \mathtt{int} \rrbracket &= \Z \\ \llbracket A \rightarrow B \rrbracket &= \llbracket B \rrbracket^{\llbracket A \rrbracket} = \llbracket A \rrbracket \rightarrow \llbracket B \rrbracket \end{align*}

Izraze \(\vdash M : A\) bomo interpretirali z elementi \(\llbracket \vdash M : A \rrbracket \in \llbracket A \rrbracket\). V splošnem interpretiramo izraze v kontektsu \[ \llbracket \Gamma \vdash M : A\rrbracket : \llbracket \Gamma \rrbracket \rightarrow \llbracket A \rrbracket \] kjer je \[ \llbracket x_1 : A_1, \dots, x_n : A_n \rrbracket := \llbracket A_1 \rrbracket \times \cdots \times \llbracket A_n \rrbracket \]

\begin{align*} \llbracket \Gamma \vdash \mathtt{true} : \mathtt{bool} \rrbracket (\gamma) &= \mathtt{tt} \\ \llbracket \Gamma \vdash \mathtt{false} : \mathtt{bool} \rrbracket (\gamma) &= \mathtt{ff} \\ \llbracket \Gamma \vdash \text{if } M \text{ then } N_1 \text{ else } N_2 A \rrbracket(\gamma) &= \begin{cases} \llbracket N_1(\gamma) \rrbracket &; \llbracket M \rrbracket(\gamma) = \mathtt{tt} \\ \llbracket N_1(\gamma) \rrbracket &; \text{sicer} \end{cases} \\ \llbracket \Gamma \vdash \underline{n} : \mathtt{int} \rrbracket(\gamma) &= n \\ \llbracket \Gamma \vdash M + N : \mathtt{int}(\gamma) \rrbracket &= \llbracket M \rrbracket(\gamma) + \llbracket M \rrbracket(\gamma) \\ \llbracket x_1 : A_1, \dots, x_n A_n \vdash x_i : A_i \rrbracket((\gamma_1, \dots, \gamma_n)) &= \gamma_i \\ \llbracket \Gamma \vdash \lambda x .\, M : A \rightarrow B \rrbracket(\gamma) &= a \in \llbracket A \rrbracket \mapsto \llbracket \Gamma, x : A \vdash M : B \rrbracket(\gamma, a) \\ \llbracket \Gamma \vdash MN : B \rrbracket(\gamma) &= \llbracket \Gamma \vdash M : A \rightarrow B\rrbracket(\gamma)\left(\llbracket \Gamma \vdash N : A\rrbracket(\gamma)\right) \end{align*}
\begin{align*} &\llbracket x : \mathtt{int} \vdash \lambda y .\, 2 * x > y + 5 : \mathtt{int} \rightarrow \mathtt{bool} \rrbracket(a): \Z \rightarrow (\Z \rightarrow \mathbf{B}) \\ = &b \in \Z \mapsto \llbracket x : \mathtt{int}, y : \mathtt{int} \vdash 2 * x > y + 5 : \mathtt{bool} \rrbracket(a, b) \\ =& b \in \Z \mapsto \begin{cases} \mathsf{tt} & \llbracket 2 * x \rrbracket(a, b) > \llbracket y + y \rrbracket(a, b) \\ \mathsf{ff} & \text{sicer} \\ \end{cases} \\ =& b \in \Z \mapsto \begin{cases} \mathsf{tt} & 2a > b + 5 \\ \mathsf{ff} & \text{sicer} \end{cases} \end{align*}
Skladnost

Za \(\Gamma \vdash M : A\) in \(M \leadsto M'\) velja \[ \llbracket \Gamma \vdash M : A \rrbracket = \llbracket \Gamma \vdash M' : A \rrbracket \]

Z indukcijo na \(M \leadsto M'\). Da pokažemo

\begin{prooftree} \AxiomC{\(M \leadsto M'\)} \UnaryInfC{\(\text{if } M \text{ then } N_1 \text{ else } N_2\) } \noLine \UnaryInfC{\(\leadsto\text{if }M' \text{ then} N_1 \text{ else } N_2\) } \end{prooftree}

pogledamo

\begin{align*} \llbracket \text{ if } M \text{ then } N_1 \text{ else } N_2 \rrbracket(\gamma) &= \begin{cases} \llbracket N_1 \rrbracket(\gamma) & \llbracket M \rrbracket(\gamma) = \mathsf{tt} \\ \llbracket N_2 \rrbracket(\gamma) & \text{sicer} \end{cases} \\ &= \begin{cases} \llbracket N_1 \rrbracket(\gamma) & \llbracket M' \rrbracket \rrbracket(\gamma) = \mathsf{tt} \\ \end{cases} \end{align*}

najprej po definiciji, potem po indukcijski predpostavki ter spet po definicji. Ostali primeri so podobni, le pri \(\beta\) redukciji moramo uporabiti lemo o substituciji.

O substituciji

Če imamo \(\Gamma, x : A \vdash M : B\) in \(\Gamma \vdash N : A\), tedaj

\begin{align*} \llbracket \Gamma \vdash M[N/x] : B \rrbracket(\gamma) &= \llbracket \Gamma, x : A \vdash M : B \rrbracket (\gamma, \llbracket \Gamma \vdash N : A \rrbracket (\gamma)) \end{align*}

Z indukcijo na \(M\).

Zadostnost (adequacy)

Če velja \(\llbracket \vdash M : \mathtt{bool} \rrbracket = \mathit{tt}\), tedaj velja \(M \leadsto^{ * } \mathtt{true}\)

Če imamo krepko normalizacijo, obstaja \(V\), da je \(M \leadsto V^{ * }\). Po skladnosti je \(\llbracket V \rrbracket = \llbracket M \rrbracket = \mathit{tt}\), zato je \(V = \mathtt{true}\).

Če je \(\llbracket M \rrbracket = \llbracket N \rrbracket\), tedaj je \(M \simeq N\).

Opazimo, da je \(\llbracket ~ \cdot ~ \rrbracket\) definirana strukturno, iz česar za \(\llbracket M \rrbracket = \llbracket N \rrbracket\) sledi \[ \llbracket \mathcal{C}[M] \rrbracket = \llbracket \mathcal{C}[N] \rrbracket \] za vse \(\mathcal{C}\).

Recimo \[ \llbracket\underbrace{ \lambda x .\, \text{if } M > 0 \text{ then } M \text{ else } 0}_{\mathcal{C}} \rrbracket = a \mapsto \begin{cases} \llbracket M \rrbracket & \llbracket M \rrbracket > 0 \\ 0 & \text{sicer} \end{cases} \] Če velja \(\mathcal{C}[M] \leadsto^{ * } \mathtt{true}\), je po skladnosti \(\llbracket \mathcal{C}[M] \rrbracket = \llbracket \mathtt{true} \rrbracket = \mathit{tt}\), zato je \(\llbracket \mathcal{C}[N] \rrbracket = \mathit{tt}\), zato po zadostnosti sledi \(\mathcal{C}[N] \leadsto^{ * } \mathtt{true}\).

\noindent Recimo, da dodamo še rekurzijo. Tedaj velja po eni strani \[ \llbracket (\mathtt{rec} \, f \, x .\, f \, x + \underline{1}) \underline{0} \rrbracket = \llbracket \mathtt{rec} \rrbracket(\underline{0}) \] po drugi strani pa \[ \llbracket (\mathtt{rec} \, f \, x .\, f \, x + \underline{1}) \underline{0} \rrbracket = \llbracket (\mathtt{rec} \, f \, x .\, f \, x + \underline{1}) \underline{0} + \underline{1} \rrbracket = \llbracket (\mathtt{rec}\, f\, x .\, f\, x + 1)0 \rrbracket + 1 \] kar pomeni da rekurzije ne moremo pravilno izraziti.

Domene

Vidimo, da za interpretacije rekurzivnih funkcij potrebujemo fiksne točke (skoraj vseh) preslikav. Ideja konstrukcije \(\mu f\) za nek Scottovo zvezen funktor \(F\) nas pripelje do domen.

Delna ureditev \((D, \leq_D)\) je domena, če

  • ima najmanjši element \(\bot_D\), i.e. \(\forall d \in D .\, \bot \leq d\)
  • vsaka veriga \(d_0, d_1, \dots\) ima natančno zgornjo mejo \(\bigvee_i d_i \in D\)

\noindent NB to je v resnici \(\omega\)-continuous partial order domain. Urejenost si predstavljamo kot "več informacij". \(\bot\) je nikjer definirana, kar pomeni da ima nič informacij. true in false sta oba definirana, a "nosita enako informacij" zato sta neprimerljiva. Funkcija, ki je nekje nedefinirana nosi manj informacij kot funkcija, ki se z njo ujema na prvotni domeni in ima več definiranih vrednosti.

  • \(X_{\bot} = X + \left\{ \bot \right\}\) kjer so vsi elementi \(X\) nad \(\bot\) in med samo neprimerljivi
  • Če imamo domeni \((D_1, \leq_1)\) in \((D_2, \leq_2)\), potem bo \[ (x_1, x_2) \leq_{D_1 \times D_2} (y_1, y_2) \iff (x_1 \leq_{D_1} y_1) \land (x_2 \leq_{D_2} y_2). \]

Naj bosta \((D_1, \leq_{D_1})\) in \((D_2, \leq_{D_2})\). Funkcija \(f : D_1 \rightarrow D_2\) je zvezna, če je monotona, i.e. \[ x \leq_{D_1} y \implies fx \leq_{D_2} fy, \] ohranja supremume verig, i.e. če je \(x_0 \leq x_1 \leq \cdots \in D_1\), velja \[ f \left( \bigvee_i x_i \right) = \bigvee_i fx_i \]

Tarski

Naj bo \((D, \leq)\) domena. Tedaj ima vsaka zvezna funkcija \(f : D \rightarrow D\) najmanjšo fiksno točko.

Definiramo \(x_0 = \bot\) in \(x_{i+1} = f(x_i)\). Po indukciji pokažemo, da je \(x_0 \leq x_1 \leq \cdots\) veriga. Ker je \(D\) domena, obstaja \(\bigvee_i x_i \in D\). Preverimo, da je \(x\) najmanjša fiksna točka za \(f\). \[ f \left( \bigvee_i x_i \right) = \bigvee_i f(x_i) = \bigvee_i x_{i+1} = \bigvee_i x_i \]

Naj bo \(y = f(y)\). Po indukciji pokažemo, da je \(x_i \leq y\) za vsak \(i\):

\begin{align*} x_0 &= \bot \leq y \\ x_{i+1} &= f(x_i) \leq f(y) = y \end{align*}

To pomeni, da je tudi \[ \bigvee_i x_i \leq y. \]

\noindent Vsak tip \(\llbracket A \rrbracket\) lahko interpretiramo z domeno \(\llbracket A \rrbracket\) tako da dodamo \(\bot\).

\begin{align*} \llbracket \mathtt{bool} \rrbracket &=\mathbb{B}_{\bot} \\ \llbracket \mathtt{int} \rrbracket &= \Z_{\bot} \\ \llbracket A \rightarrow B \rrbracket &= [\llbracket A \rrbracket \rightarrow \llbracket B \rrbracket] \end{align*}

kjer je \([D_1 \rightarrow D_2]\) domena vseh zveznih funkcij \(D_1 \rightarrow D_2\) urejene po točkah.

Kontekst interpretiramo s produktom \[ \llbracket x_1 : A, \dots, x_n : A_n \rrbracket = \llbracket x_1 : A \rrbracket \times \dots \times \llbracket x_n : A_n \rrbracket \] Tedaj lahko vsak izraz \(\Gamma \vdash M : A\) interpretiramo z zvezno preslikavo \(\llbracket \Gamma \vdash M : A \rrbracket : \llbracket \Gamma \rrbracket \rightarrow \llbracket A \rrbracket\).

Torej je

\begin{align*} \llbracket x_i \rrbracket(\gamma) &= \gamma_i \\ \llbracket M N \rrbracket(\gamma) &= \llbracket M \rrbracket (\gamma)(\llbracket N \rrbracket (\gamma)) \end{align*}

Nimamo pa zadostnosti. Na primer, velja \[ \llbracket (\lambda .\, \mathtt{true})(\Omega) \rrbracket = \mathit{tt} \] ampak ta izraz ne bo prišel do true v končno mnogo korakih. Problem rešimo tako, da definiramo \[ \llbracket \lambda x.\, M \llbracket(\gamma) = a \mapsto \begin{cases} \bot & a = \bot \\ \llbracket M \rrbracket(\gamma, a) \end{cases} \] ker želimo zadostnost. Uporabimo torej stroge funkcije. \[ \llbracket M + N \rrbracket(\gamma) = \begin{cases} \bot & \text{če } \llbracket M \rrbracket = \bot \lor \llbracket N \rrbracket = \bot \\ \llbracket M \rrbracket + \llbracket N \rrbracket & \text{sicer} \end{cases} \] Končno definiramo še rekurzivne funkcije. \[ \llbracket \mathtt{rec}\, f\, x .\, M \rrbracket(\gamma) = \mu \Phi \] kjer je \[ \Phi(g) = a \mapsto \llbracket M \rrbracket(\gamma, g, a) \] oziroma \[ \mu g .\, a \mapsto \llbracket M \rrbracket(\gamma, g, a). \]

Za vse primere moramo pokazati, da dobimo zvezne funkcije. Oglejmo si rekurzijo. Najprej moramo pokazati, da imamo zvezno funkcijo.

\begin{align*} \mathtt{fix} &: [D \rightarrow D] \rightarrow D\\ \mathtt{fix} \, f &= \mu f \end{align*}

je zvezna funkcija

Naj bo \(f \leq g\). Tedaj je \[ \bot \leq \bot \quad f \bot \leq g \bot \quad f(f(\bot)) \leq g(f(\bot)) \leq g(g(\bot)) \] zato je \[ \mu f = \bigvee_i f^i \bot \leq \bigvee_i g^i \bot = \mu g, \] torej je fix monotona.

Pokažimo, da je zvezna. \[ f_0 \leq f_1 \leq \cdots \] Potem je

\begin{align*} \mathtt{fix} \left( \bigvee_i f_i \right) &= \bigvee_j (\bigvee_i f_i)^j \bot \\ &= \bigvee_j \bigvee_i (f_i^j \bot) \left(= \bigvee_k f_k^k \bot \right)\\ &= \bigvee_i \left( \bigvee_j f_i^j \bot \right) \\ &= \bigvee_i \mathtt{fix} \, f_i \end{align*}

NB da je \[ \left( \bigvee_i f_i \right)^{j +1} \bot = \left( \bigvee_i f_i \right)^j \left( \left( \bigvee_i f_i \right) \bot \right) = \left( \bigvee_i f_j \right)^j \left( \bigvee_i (f_i \bot) \right) = \bigvee_i \left( \left( \bigvee_i f_i \right)^j (f_i \bot) \right) \]

2026-05-08 Brezplačni izreki (cont.)

Če imamo množice \(X_1, \dots, X_n\) in \(Y_i\) za vse parametre \(\alpha_1, \dots, \alpha_n\) ter relacije \(R_i \subseteq X_i \times Y_i\), lahko definiramo relacije \( \llbracket A \rrbracket_{\vec{R}} \subseteq \llbracket A \rrbracket_{\vec{X}} \times \llbracket A \rrbracket_{\vec{Y}}\) za poljuben tip \(A\) kot

\begin{align*} m \llbracket \text{int} \rrbracket_{\vec{R}}n &\iff m = n \\ b_1 \llbracket \text{bool} \rrbracket_{\vec{R}} b_2 &\iff b_1 = b_2 \\ x \llbracket \alpha_i \rrbracket_{\vec{R}} y &\iff x R_i y \\ (x_1, x_2) \llbracket A \times B \rrbracket_{\vec{R}} &\iff x_1 \llbracket A \rrbracket_{\vec{R}} y_1 \land x_2 \llbracket A \rrbracket_{\vec{R}} y_2 \\ \llbracket (\alpha \rightarrow \text{bool}) \rightarrow \alpha \text{ list } \rightarrow \alpha \text{ list } \rrbracket &= ? \\ xs \llbracket A \text{ list } \rrbracket yt &\iff \abs{xs} = \abs{ys} \land \forall k .\, xs_k \llbracket A \rrbracket_{\vec{R}} ys_k \\ f \llbracket A \rightarrow B \rrbracket_{\vec{R}} g &\iff \forall x, y .\, x \llbracket A \rrbracket y \implies fx \llbracket B \rrbracket_{\vec{R}} gy \end{align*}

Naj bo \(\Gamma \vdash M : A\), kjer je \(\Gamma = x_1 : A_1 ,\dots, x_n : A_n\). Tedaj za poljubne dodelitve \(\vec{x}, \vec{y}, \vec{R}\) in poljubne \[ a_1, a_1' \in \llbracket A_1 \rrbracket_{\vec{R}}, \dots, a_n, a_n' \in \llbracket A_n \rrbracket_{\vec{R}} \] velja \[ {\llbracket \Gamma \vdash M : A \rrbracket}_{\vec{X}}(a_1, \dots, a_n) \llbracket A \rrbracket_{\vec{R}} \llbracket \Gamma \vdash M : A \rrbracket_{\vec{y}}(a_1', \dots, a_n'). \]

Dokaz poteka z indukcijo na \(\Gamma \vdash M : A\). Če imamo \[

\begin{bprooftree} \AxiomC{} \UnaryInfC{\(\Gamma \rightarrow x_i : A_i\) } \end{bprooftree}

\] tedaj je

\begin{align*} \llbracket \Gamma \vdash x_i : A_i \rrbracket_{\vec{x}} (\vec{a}) &= a_i \\ \llbracket \Gamma \vdash y_i : A_i \rrbracket_{\vec{y}} (\vec{a}) &= a'_i \\ \end{align*}

Iz predpostavke sledi \(a_i \llbracket A_i \rrbracket_{\vec{R}} a_i'\).

Če imamo aplikacijo \[

\begin{bprooftree} \AxiomC{\(\Gamma \vdash M' : A' \rightarrow A\)} \AxiomC{\(\Gamma \vdash N : A'\)} \BinaryInfC{\(M' N : A\)} \end{bprooftree}

\] imamo \[ \llbracket \Gamma \vdash M' N : A \rrbracket_{\vec{x}}(\vec{a}) = \llbracket \Gamma \vdash M' : A' \rightarrow A \rrbracket(\vec{a}) (\llbracket \Gamma \vdash N : A' \rrbracket_{\vec{x}}(\vec{a})) \] in \[ \llbracket \Gamma \vdash M' N : A \rrbracket_{\vec{y}}(\vec{a}') = \llbracket \Gamma \vdash M' : A' \rightarrow A \rrbracket(\vec{a}') (\llbracket \Gamma \vdash N : A' \rrbracket_{\vec{y}}(\vec{a}')). \] Po indukcijski predpostavki velja \[ \llbracket M' \rrbracket_{\vec{x}} \llbracket A' \rightarrow A \rrbracket_{\vec{R}} \llbracket M' \rrbracket_{\vec{y}} \] in podobno za \(N\). Po definicijii \(\llbracket A' \rightarrow A \rrbracket_{\vec{R}}\) iz \(\llbracket N \rrbracket \llbracket A' \rrbracket \llbracket N \rrbracket\) sledi \[ \llbracket M \rrbracket (\llbracket N \rrbracket) \llbracket A \rrbracket \llbracket M \rrbracket(\llbracket N \rrbracket). \] Ostalo podobno.

Poglejmo si \(\alpha \text{ list} \rightarrow \alpha \text{ list}\) . Naj bo \(\llbracket M \rrbracket_{x} \llbracket \alpha \text{ list} \rightarrow \alpha \text{ list} \rrbracket_R \llbracket M \rrbracket_y\) in vzemimo poljubni \(x, y\) ter poljubno funckijo \(g\).

Relacija naj bo graf: \(xRy \iff gx = y\). Označimo \(f_x = \llbracket M \rrbracket_x\) in \(f_y = \llbracket M \rrbracket_y\). Velja \[ f_x \llbracket \alpha \text{ list} \rightarrow \alpha \text{ list} \rrbracket_R f_y \iff \forall xs \llbracket \alpha \text{ list} \rrbracket_R ys \implies f_x xs \llbracket \alpha \text{ list} \rrbracket_R f_y ys. \] Vidimo, da je \(xs \llbracket \alpha \text{ list} \rrbracket ys\) natanko tedaj, ko je \(ys = \operatorname{map} g \, xs\). Torej velja \[ \forall xs \llbracket \alpha \text{ list} \rrbracket_R ys \implies f_x xs \llbracket \alpha \text{ list} \rrbracket_R f_y ys \iff \forall xs, yx ,\cdot ys = \operatorname{map}g\, xs \implies f_y ys = \operatorname{map}g (f_x xs) \] oziroma \[ f_y \circ (\operatorname{map} g) = (\operatorname{map} g) \circ f_x. \]

Podobno za \(M : \alpha \text{ list } \rightarrow \alpha\) dobimo \[ \implies f_y \circ \operatorname{map} g = g \circ fx \]

Oglejmo si še \((\alpha \rightarrow \text{bool}) \rightarrow \alpha \text{ list} \rightarrow \alpha \text{ list}\).

\begin{align*} \llbracket M \rrbracket_x &= f_x : (X \rightarrow \mathbb{B} \rightarrow X^{ * } \rightarrow X^{ * }) \\ \llbracket M \rrbracket_y &= f_y : (Y \rightarrow \mathbb{B} \rightarrow Y^{ * } \rightarrow Y^{ * }) \end{align*}

in imamo relacijo \[ f_x \llbracket (\alpha \rightarrow \text{bool}) \rightarrow \alpha \text{ list} \rightarrow \alpha \text{ list} \rrbracket f_y. \] Potem računamo

\begin{align*} \forall &p_x : X \rightarrow \mathbb{B}, p_y : Y \rightarrow \mathbb{B} .\, p_x \llbracket \alpha \rightarrow \text{bool} \rrbracket p_y \\ &\implies \forall xs : X^{ * }, ys : Y^{ * } .\, xs \llbracket \alpha \text{ list} \rrbracket ys \\ &\implies f_x\, p_x\, xs \llbracket \alpha \text{ list} \rrbracket f_y \, p_y \, ys \end{align*}

Kdaj je \(p_x \llbracket \alpha \rightarrow \text{bool} \rrbracket p_y\)? Če je \(y = gx\), je \(p_x x \llbracket \text{bool} \rrbracket p_y y\), torej \[ p_x x = p_y(gx) \text{ oz. } p_x = p_y \circ g. \] Vse skupaj je torej ekvivalentno \[ f_y p_y (\operatorname{map} g \, xs) = \operatorname{map} g(f_x (p_y \circ g) xs) \] še lepše, če pišemo \(q = p_y\) in \(p = p_x\), \[ (f_y q) \circ \operatorname{map} g = \operatorname{map} g \circ (f_x(q \circ g)). \]

Vzemimo \(M : \alpha \rightarrow \alpha\) ter \(i_x = \llbracket M \rrbracket_x\) in \(i_y = \llbracket M \rrbracket_y\). Za vse \(R \subseteq X \times Y\) velja \[ i_x \llbracket \alpha \rightarrow \alpha \rrbracket i_y \iff \forall x, y .\, xRy \implies i_X x R i_Y y. \] Pokazati hočemo, da je \(i_X\) identiteta.

Vzemimo poljubna \(a\in X, b \in Y\) in definiramo \[ R_{a,b} = \left\{ (a, b) \right\}. \] Ker velja \(aR_{a,b} b\) mora veljati tudi \(i_X a R_{a, b} i_Y b\). To pomeni, da mora biti \(i_Xa = a\) in \(i_Xb = b\), kar lahko naredimo za vse \(a\) in \(b\).

Računski učinki

Programe \(M : A \rightarrow B\) smo intepretirali s funkcijami \(\llbracket A \rrbracket \rightarrow \llbracket B \rrbracket\). Toda programi lahko sprožajo učinke (branje/pisanje z IO naprav, naključna izbira, izjeme, nedeterminizem, ipd.), ki jih funkcije ne zajamejo.

Za začetek si oglejmo operacijsko semantiko. Najprej si prilagodimo osnovni jezik. Zaradi učinkov želimo neučakano izvajanje.

Definirali bomo drobnozrnati neučakani λ-račun (fine-grain call-by-value/fgcbv). Izraze strogo ločimo na vrednosti \[ V ::= x \mid \text{true} \mid \text{false} \mid \underline{n} \mid \lambda x .\, M \] in izračune \[ M, N ::= V\, W \mid V_1 + V_2 \mid V_1 * V_2 \mid \text{if } V \text{ then } M_1 \text{ else } M_2 \mid \operatorname{return} V \mid \operatorname{let} x = M \operatorname{in} N \]

Izrazi kot \(\lambda x .\, x\) ali \((\underline{1} + \underline{2}) + \underline{3}\) nista sintaktično veljavna, pisati moramo recimo \(\lambda x .\, \operatorname{return} x\) in \(\operatorname{let} x = \underline{1} + \underline{2} \operatorname{in} x + \underline{3}\).

V praksi za ločitev poskrbi programski jezik.

\noindent Ta pristop je znan pod imenom "A-normal form". Poskrbi, da je vedno natanko ena točka izvajanja. Ideja je podobna SSA.

Oglejmo si operacijsko semantiko.

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\((\lambda x.\, M)V \leadsto M[V/x]\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\underline{m} + \underline{n} \leadsto \operatorname{return} m + n\) } \end{bprooftree} \quad \text{(podobno za ostale)} \\ \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{if} \texttt{true} \operatorname{then} M_1 \operatorname{else} M_2 \leadsto M_1\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{if} \texttt{false} \operatorname{then} M_1 \operatorname{else} M_2 \leadsto M_2\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(M \leadsto M'\)} \UnaryInfC{\(\operatorname{let} x = M \operatorname{in} N \leadsto \operatorname{let} x = M' \operatorname{in} N\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{let} x = \operatorname{ret} V \operatorname{in} N \leadsto N[V/x]\)} \end{bprooftree} \end{gather*}

S tem zapisom se bistveno zmanjša število pravil na vsakem koraku.

Podati moramo še pravila za tipe \(\Gamma \vdash V : A\) in \(\Gamma \vdash M : A\) Večinoma imamo običajna pravila

\begin{gather*} \begin{bprooftree} \AxiomC{\((x : A) \in \Gamma\)} \UnaryInfC{\(\Gamma \vdash_V x : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma, x : A \vdash_C M : B\)} \UnaryInfC{\(\Gamma \vdash_V \lambda x .\, M : A \rightarrow B\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash_V V : A \rightarrow B\)} \AxiomC{\(\Gamma \vdash_V W : A\)} \BinaryInfC{\(\Gamma \vdash_C V W : B\)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Gamma \vdash_V V : A\)} \UnaryInfC{\(\Gamma \vdash_C \operatorname{return} V : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash_C M : A\)} \AxiomC{\(\Gamma, x : A \vdash_C N : B\)} \BinaryInfC{\(\Gamma \vdash_C \operatorname{let} x = M \operatorname{in} N : B\)} \end{bprooftree} \end{gather*}

Če imamo programe, ki lahko sprožijo učinke, i.e. \(\Gamma \vdash_C M : A! \mathcal{E}\), dobimo

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma, x : A \vdash_C M : B! \mathcal{E}\)} \UnaryInfC{\(\Gamma \vdash_V \lambda x .\, M : A \xrightarrow{\mathcal{E}} B! \mathcal{E}\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash_V V : A \xrightarrow{\mathcal{E}} B\)} \AxiomC{\(\Gamma \vdash_V W : A\)} \BinaryInfC{\(\Gamma \vdash_C V W : B\)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(\Gamma \vdash_V V : A\)} \UnaryInfC{\(\Gamma \vdash_C \operatorname{return} V : A!\emptyset\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash_C M : A!\mathcal{E}_1\)} \AxiomC{\(\Gamma, x : A \vdash_C N : B!\mathcal{E}_2\)} \BinaryInfC{\(\Gamma \vdash_C \operatorname{let} x = M \operatorname{in} N : B!\mathcal{E}_1 \cup \mathcal{E}_2\)} \end{bprooftree} \end{gather*}

Imamo standardni izreke o varnosti, ohranitvi, in napredku.

Če velja \(\vdash_C M : A\), tedaj

  • bodisi \(M \leadsto M'\) za nek \(\vdash M' : A\)
  • bodisi \(M = \operatorname{return} V\) za nek \(\vdash_V V : A\).

Izjeme

Razširimo jezik z izjemami. \[ M ::= \cdots \mid \operatorname{raise} \mid \operatorname{try} M \operatorname{with} N \] s pravili

\begin{gather*} \begin{bprooftree} \AxiomC{\(M \leadsto M'\)} \UnaryInfC{\(\operatorname{try} M \operatorname{with} N \leadsto \operatorname{try} M' \operatorname{with} N\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{try} \operatorname{raise} \operatorname{with} N \leadsto N\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{try}(\operatorname{ret} V) \operatorname{with} N \leadsto \operatorname{ret} V\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{let} x = \operatorname{raise} \operatorname{in} N \leadsto \operatorname{raise}\) } \end{bprooftree} \end{gather*}

Za \(\Gamma \vdash_C M : A\) dodamo še

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\Gamma \vdash \operatorname{raise} : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \AxiomC{\(\Gamma \vdash N : A\)} \BinaryInfC{\(\Gamma \vdash \operatorname{try} M \operatorname{with} N : A\)} \end{bprooftree} \end{gather*}

To nadgradi izrek o varnosti.

Varnost

Če velja \(\vdash_C M : A\), tedaj

  • bodisi \(M \leadsto M'\) za nek \(\vdash M' : A\)
  • bodisi \(M = \operatorname{return} V\) za nek \(\vdash_V V : A\)
  • bodisi \(M = \operatorname{raise}\), če je \(\mathcal{E} \neq \emptyset\).

Pomnilnik

\[ M ::= \cdots \mid l := V \mid !l \] kjer

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(l := \underline{n}, s \leadsto \operatorname{return} (), s[l \mapsto n]\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(s(l) = n\)} \UnaryInfC{\(!l, s \leadsto \operatorname{return} \underline{n}, s\) } \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\(M, s \leadsto M', s'\)} \UnaryInfC{\(\operatorname{let} x = M \operatorname{in} N, s \leadsto \operatorname{let} x = M' \operatorname{in} N, s'\) } \end{bprooftree} \end{gather*}

Nedeterminizem

\[ M ::= \cdots \mid M_1 \oplus M_2 \] Potem za \(M \leadsto M'\) dobimo

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(M_1 \oplus M_2 \leadsto M_1\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(M_1 \oplus M_2 \leadsto M_2\) } \end{bprooftree} \end{gather*}

IO

\[ M ::= \cdots \mid \operatorname{print} V \] in imamo semantiko malih korakov \(M, \sigma \leadsto M', \sigma'\). Semantika velikih korakov bi imela obliko \(M \Downarrow V, \sigma\).

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{print} \underline{n} \Downarrow (), [n]\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(M \Downarrow V, \sigma\)} \AxiomC{\(N[V/x] \Downarrow W, \sigma'\)} \BinaryInfC{\(\operatorname{let} x = M \operatorname{in} N \downarrow W, \sigma + \sigma'\)} \end{bprooftree} \end{gather*}

Monade

Recimo, da tip \(A\) interpretiramo z množico \(\llbracket A \rrbracket\). Tedaj lahko vrednost interpretiramo kot prej \[ \llbracket \Gamma \vdash_V V : A \rrbracket : \llbracket \Gamma \rrbracket \rightarrow \llbracket A \rrbracket \] izračune pa odvisno od učinka.

Izjeme

\begin{align*} \llbracket \Gamma \vdash_L \vdash M : A \rrbracket : \llbracket \Gamma \rrbracket &\rightarrow \llbracket A \rrbracket + 1 \\ \llbracket \operatorname{raise} \rrbracket(\gamma) &= \iota_2(*) \\ \llbracket \operatorname{let} x = M \operatorname{in} N \rrbracket(\gamma) &= \begin{cases} \llbracket N \rrbracket(\gamma, a) & \llbracket M \rrbracket(\gamma) = \iota_1(a) \\ \iota_2( * ) & \llbracket M \rrbracket(\gamma) = \iota_2( * ) \end{cases} \\ \llbracket \operatorname{try} M \operatorname{with} N \rrbracket(\gamma) &= \begin{cases} \iota_1(a) & \llbracket M \rrbracket(\gamma) = \iota_1(a) \\ \llbracket N \rrbracket(\gamma) & \llbracket M \rrbracket(\gamma) = \iota_2( * ) \end{cases} \\ \llbracket \operatorname{return} V \rrbracket(\gamma) &= \iota_1(\llbracket V \rrbracket(\gamma)) \end{align*}

Pomnilnik

Vzamemo \(\mathbb{S} = \Z^{\mathbb{L}}\).

\begin{align*} \llbracket \Gamma \vdash_C M : A \rrbracket : \llbracket \Gamma \rrbracket \times \mathbb{S} & \rightarrow \llbracket A \rrbracket \times \mathbb{S} \\ \llbracket \operatorname{return} V \rrbracket(\gamma, s) &= (\llbracket V \rrbracket(\gamma), s)\\ \llbracket !l \rrbracket(\gamma, s) &= (s(l), s) \\ \llbracket l := v \rrbracket(\gamma, s) &= ( * , s[l \mapsto (\llbracket v \rrbracket(\gamma))]) \\ \llbracket \operatorname{let} x = M \operatorname{in} N \rrbracket(\gamma, s) &= \llbracket N \rrbracket((\gamma, a), s') \end{align*}

kjer je \(\llbracket M \rrbracket(\gamma, s) = (a, s')\). Funkcijski tip tu postane \(\llbracket A \rightarrow B \rrbracket = \llbracket A \rrbracket \times \mathbb{S} \rightarrow \llbracket B \rrbracket \rightarrow \llbracket B \rrbracket \mathbb{S}\). To je isto kot \[ \llbracket A \rightarrow B \rrbracket \rightarrow (\mathbb{S} \rightarrow \llbracket B \rrbracket \times \mathcal{S}). \]

Nedeterminizem

\[ \llbracket M \rrbracket : \llbracket \Gamma \rrbracket \rightarrow \pot \llbracket A \rrbracket \]

\begin{align*} \llbracket \operatorname{return} V \rrbracket(\gamma) &= \left\{ \llbracket V \rrbracket(\gamma) \right\} \\ \llbracket M_1 \oplus M_2 \rrbracket(\gamma) &= \llbracket M_1 \rrbracket(\gamma) \cup \llbracket M_2 \rrbracket(\gamma) \\ \llbracket \operatorname{let} x = M \operatorname{in} N \rrbracket(\gamma) &= \bigcup\limits_{a \in \llbracket M \rrbracket(\gamma)}^{} \llbracket N \rrbracket(\gamma, a) \\ \end{align*}

Funkcije imajo obliko \(\llbracket A\rightarrow B \rrbracket = \llbracket A \rrbracket \rightarrow \pot \llbracket B \rrbracket\).

Rdeča nit

V vsakem primeru slikamo iz \(\llbracket \Gamma \rrbracket\) v spremenjen tip. Imamo

  1. konstrukcijo na množicah \((- + 1, \mathbb{S} \rightarrow - \times \mathbb{S}, \pot, \dots)\)
  2. interpretacijo za return
  3. Interpretacijo za veriženje
  4. interpretacije za specifične operacije.

Ta konstrukcija na množicah je funktor. Skupaj z return in veriženjem dobimo monado.

Monada je podana kot \((T, \eta, \bind)\) je sestavljena iz

  • endofunktorja \(T : \Class{Set} \rightarrow \Class{Set}\)
  • družine preslikav \((\eta_X : X \rightarrow TX)_X\)
  • družine preslikav \((\bind_{X, Y} : TX \rightarrow (X \rightarrow TY) \rightarrow TY)_{X, Y}\)

da velja:

  1. \(m \bind_{X, X} \eta_X = m\), kar ustreza \(\operatorname{let} x = M \operatorname{in} \operatorname{return} x \cong M\)
  2. \(\eta_X(a) \bind_{X, Y} k = k(a) \), kar ustreza \(\operatorname{let} x = \operatorname{return} V \operatorname{in} N \cong N[V/x]\)
  3. Za vse \(m \in TX\), \(k : X \rightarrow TY\), \(k' : Y \rightarrow TZ\) velja \[ (m \bind_{X, Y} k) \bind_{Y, Z} k' = m \bind_{X, Z} (a \mapsto k(a) \bind_{Y, Z} k') \] To ustreza \[ \operatorname{let} y = (\operatorname{let} x = M \operatorname{in} N) \operatorname{in} N' \cong \operatorname{let} x = M \operatorname{in} (\operatorname{let} y = N \operatorname{in} N') \] Tu je majhna razlika, ker na desni vstavimo \(x\) v \(N'\), kar pomeni da to velja le, če \(x \not\in \operatorname{fv}(N' )\).

Monado lahko ekvivalentno predstavimo kot \((T, \eta, \mu)\) ali z \((T, \eta, -^{+})\) s kleislijevim dvigom \[ k^+ : TX \rightarrow TY. \]

Interpretacija dznlr (fgcbv) z monado

\begin{align*} \llbracket A \rightarrow B \rrbracket &= \llbracket A \rrbracket \longrightarrow T \llbracket B \rrbracket \\ \llbracket \Gamma \vdash_V V : A \rrbracket &: \llbracket \Gamma \rrbracket \rightarrow \llbracket A \rrbracket \\ \llbracket \Gamma \vdash_C M : A ! \xi \rrbracket &: \llbracket \Gamma \rrbracket \rightarrow T_{\xi} \llbracket A \rrbracket \\ \llbracket \vdash \operatorname{return} V : A\rrbracket(\gamma) &= \eta_{\llbracket A \rrbracket}(\llbracket V \rrbracket(\gamma)) \\ \llbracket \Gamma \vdash \operatorname{let} x = M \operatorname{in} N : B \rrbracket(\gamma) &= \llbracket M \rrbracket(\gamma) \bind_{\llbracket A \rrbracket, \llbracket B \rrbracket} (a \mapsto \llbracket N \rrbracket(\gamma, a)) \end{align*}

Učinki

Ideja od zadnjič je, da vsak učinek zapišemo z algebrajsko teorijo. Algebrajska teorija je množica operacij in enačb med njimi.

Nedeterminizem je podan kot

\begin{align*} \Sigma &= \left\{ (\vee) : 2, \bot : 0 \right\} \\ x \vee (y \vee z) &= (x \vee y) \vee z \\ x \vee y &= y \vee x \\ x \vee x &= x \\ x \vee \bot &= x \end{align*}

Zakodiramo lahko tudi druge stvari, recimo pomnilnik z eno logično vrednostjo. Imeli bomo 3 operacije. Namesto da imamo \(\operatorname{get} : \operatorname{unit} \rightarrow \operatorname{bool} \), našemu \(\operatorname{get}\) podamo dve kontinuaciji glede na vrednost pomnilnika.

\begin{align*} \Sigma &= \left\{ \operatorname{get} : 2, \operatorname{set}_0 : 1, \operatorname{set}_1 : 1 \right\} \\ \operatorname{get}(\operatorname{get}(x_{00}, x_{01}), \operatorname{get}(x_{10}, x_{11})) &= \operatorname{get}(x_{00}, x_{11}) \\ \operatorname{set}_a(\operatorname{get}(x_0, x_1)) &= \operatorname{set}_a(x_a) \\ \operatorname{set}_a(\operatorname{set}_b(x)) &= \operatorname{set}_b(x) \\ \operatorname{get}(\operatorname{set}_0(x), \operatorname{set}_1(x)) &= x \end{align*}
let _ = (set0 ∨ set1)
let x = get
return x + 2

Primer modela za to teorijo je \(\mathbb{B} \rightarrow \mathbb{B}\);

\begin{align*} \llbracket \operatorname{get} \rrbracket : &(\mathbb{B} \rightarrow \mathbb{B})^2 \rightarrow (\mathbb{B} \rightarrow \mathbb{B}) \\ \llbracket \operatorname{get} \rrbracket(f, g) &= a \mapsto \begin{cases} f\, 0 & a = 0 \\ g\, 1 & a = 1 \end{cases} \\ \llbracket \operatorname{set}_a \rrbracket : &(\mathbb{B} \rightarrow \mathbb{B}) \rightarrow (\mathbb{B} \rightarrow \mathbb{B}) \\ \llbracket \operatorname{set}_a \rrbracket(f) &= \_ \mapsto f\, a \end{align*}

Potem je recimo

\begin{align*} \llbracket \operatorname{get} \rrbracket(\llbracket \operatorname{get} \rrbracket (f, g), \llbracket \operatorname{get} \rrbracket(h, l) ) &= a \mapsto \begin{cases} (\llbracket \operatorname{get} \rrbracket(f, g)) 0 & a = 0 \\ (\llbracket \operatorname{get} \rrbracket(h, l)) 1 & a = 1 \end{cases} \\ &= a \mapsto \begin{cases} g\, 0 & a = 0 \\ l\, 1 & a = 1 \end{cases} \\ &= \llbracket \operatorname{get}(f, l) \rrbracket \end{align*}

Izračune interpretiramo v prostem modelu. Naredimo kvocient množice vseh izrazov/dreves glede na enačbe teorije. Pri nedeterminizmu vidimo, da je \(F X = \pot_{\operatorname{fin} X}\).

Kaj je prosti model za teorijo pomnilnika? Normalna oblika izrazov je \[ \operatorname{get}(\operatorname{set}_a(x), \operatorname{set}_b(y)) \] in dobimo \[ FX \cong (\mathbb{B} \times X)^2 \cong \mathbb{B} \rightarrow \mathbb{B} \times X \]

Z algebrajskimi teorijami se izognemu težavam z monadami. Specifično, komponiranje deluje. Vzamemo unijo obeh teorij in dodamo potencialne enačbe za interakcijo. Oglejmo si še operacijsko semantiko.

V večini primerov prosti model porodi pričakovano monado. Protiprimer je monada za kontinuacije. \[ TX = R^{R^X} = (X \rightarrow R) \rightarrow R \] kjer je \(R\) množica končnih rezultatov.

Drobnozrnati neučakani \(\lambda\)-račun v luči algebrajskih učinkov

Za osnovo si izberemo algebrajsko teorijo, ki predstavlja učinke, s katerimi želimo imeti opravka. Da naredimo operacije bolj uporabne, jih poplošimo na dva načina.

  • Členosti (arity) operacij ne bodo naravna števila, ampak tipi.
  • Namesto \(\operatorname{op}(X_1, \dots, X_n)\) za \(\operatorname{op} : n \in \Sigma\) bomo imeli \[ \operatorname{op}((X_a)_{a \in \llbracket A \rrbracket}) \] za \(\operatorname{op} : A \in \Sigma\).
  • Recimo, \(\operatorname{get} : \operatorname{bool}, \operatorname{set}_0 : \operatorname{unit}, \operatorname{set}_1 : \operatorname{unit}, \vee : \operatorname{bool}, \bot : \operatorname{empty}\).
  • Posplošitev deluje tudi za števne in neštevne tipe.
  • Operacije bomo parametrizirali in dobili namesto družine \[ (\operatorname{op}_p : A)_{p \in \llbracket P \rrbracket} \] parametrizirano operacijo \(\operatorname{op} : P \rightarrow A\). (to ni funkcijski tip)
  • \(\operatorname{get} : \operatorname{unit} \rightarrow \operatorname{bool}\)
  • \(\operatorname{set} : \operatorname{bool} \rightarrow \operatorname{unit}\)
  • \(\operatorname{read} : \operatorname{unit} \rightarrow \operatorname{string}\)
  • \(\operatorname{write} : \operatorname{string} \rightarrow \operatorname{unit}\)

Enačbe lahko prilagodimo, recimo \[ \operatorname{set}(a; \_.\operatorname{get}((); b.x(b))) = \operatorname{set}(a; \_.x(a)) \] Vrednosti in izračuni so isti kot prej

\begin{align*} V &\Coloneqq \cdots \\ M &\Coloneqq \cdots \mid \operatorname{return} V \mid \operatorname{let} x = M \operatorname{in} N \mid \operatorname{op}(V; \, x.M) \end{align*}

Tipe določamo kot

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma \vdash_V V : A\)} \UnaryInfC{\(\Gamma \vdash_C \operatorname{ret} V : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash_C M : A\)} \AxiomC{\(\Gamma, x : A \vdash_C N : B\)} \BinaryInfC{\(\Gamma \vdash_C \operatorname{let} x = M \operatorname{in} N : B\)} \end{bprooftree} \\ \begin{bprooftree} \AxiomC{\((\operatorname{op} : P \rightarrow A) \in \Sigma\)} \AxiomC{\(\Gamma \vdash_V V : P\)} \AxiomC{\(\Gamma, x : A \vdash_C M : B\)} \TrinaryInfC{\(\Gamma \vdash_C \operatorname{op} (V; \,x.M) : B\)} \end{bprooftree} \end{gather*}

Operacijski semantiki dodamo pravilo

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{let} x = \operatorname{op}(V;\, x.M) \operatorname{in} N \leadsto \operatorname{op}(V;\, y. \operatorname{let} x = M \operatorname{in} N)\)} \end{bprooftree} \end{gather*}

Prestrezniki učinkov

Učinke opisujemo z operacijami \((\operatorname{op} : P \rightarrow A) \in \Sigma\), eg

\begin{align*} \operatorname{get} : &\operatorname{unit} \rightarrow \operatorname{int} \\ \operatorname{set} :& \operatorname{int } \rightarrow \operatorname{unit} \\ \operatorname{choose} :& \operatorname{unit} \rightarrow \operatorname{bool} \\ \operatorname{rand} :& \operatorname{float} \rightarrow \operatorname{bool} \\ \end{align*}

Imamo \(M \Coloneqq \operatorname{op}(V; \, x.\, M)\), kjer je \(V\) parameter, \(M\) pa kontinuacija. Pravila so

\begin{gather*} \begin{bprooftree} \AxiomC{\((\operatorname{op} : P \rightarrow A) \in \Sigma\)} \AxiomC{\(\Gamma \vdash_V V : P\)} \AxiomC{\(\Gamma, x : A \vdash_C M : B\)} \TrinaryInfC{\(\Gamma \vdash_C \operatorname{op}(V;\, x.M) : B\)} \end{bprooftree} \quad \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\operatorname{let} x = \operatorname{op}(V;\, x.M) \operatorname{in} N \leadsto \operatorname{op}(V;\, y. \operatorname{let} x = M \operatorname{in} N)\)} \end{bprooftree} \end{gather*} \begin{align*} \operatorname{let} x &= M_1 \oplus M_2 \operatorname{in} N \\ &\leadsto (\operatorname{let} x = M_1 \operatorname{in} N) \oplus (\operatorname{let} x = M_2 \operatorname{in} N) \\ M_1 \oplus M_2 &\coloneqq \operatorname{choose}(();\, b. \operatorname{if} b \operatorname{then} M_1 \operatorname{else} M_2) \end{align*}

Velja izrek o varnosti.

Če velja \(\vdash_C M : A\), tedaj

  1. obstaja \(\vdash_C M' : A\), da je \(M \leadsto M'\)
  2. obstaja \(\vdash_V V : A\), da je \(M = \operatorname{return} V\)
  3. obstajajo \((\operatorname{op} : P \rightarrow B) \in \Sigma\), \(\vdash_V V : P\) in \(x : B \rightarrow_C M'\), da je \[ M = \operatorname{op}(V;\, x.M') \]
\begin{align*} \operatorname{let} x = \operatorname{choose}(();\, b \operatorname{if} b \operatorname{then} M_1 \operatorname{else} M_2) \operatorname{in} N &\leadsto \operatorname{choose}(();\, b. \operatorname{let} x = (\operatorname{if} b \operatorname{then} M_1 \operatorname{else} M_2) \operatorname{in} N) \\ &\cong \operatorname{choose} ((); b . \operatorname{if} b \operatorname{then}(\operatorname{let} x = M_1 \operatorname{in} N) \operatorname{else} (\operatorname{let} x = M_2 \operatorname{in} N)) \end{align*}

Definiramo okrajšavo (generični učinek) \[ \underline{\operatorname{op}}(V) \coloneqq \operatorname{op}(V;\, x . \operatorname{return} x). \] Tedaj je \[ \operatorname{op}(V;\, x. \operatorname{M}) \cong \operatorname{let} x = \underline{\operatorname{op}}(V) \operatorname{in} M \]

Alternativi za operacijsko semantiko so

  • Veliki koraki \(M \Downarrow R\), kjer je \[ R \Coloneqq \operatorname{return} V \mid \operatorname{op}(V; \, (R_i)_i) \] in

    \begin{gather*} \begin{bprooftree} \AxiomC{\(M[V_i / x] \Downarrow R_i\)} \AxiomC{za vse vrednosti \(V_1,\dots\) iz členosti operacij} \BinaryInfC{\(\operatorname{op}(V;\, x. \operatorname{M} \Downarrow \operatorname{op}(V;\, (R_i)_i))\)} \end{bprooftree} \end{gather*}
  • Srednji koraki:

    \begin{prooftree} \AxiomC{\(\text{za vsako vrednost}\vdash W : A\)} \UnaryInfC{\(\operatorname{op}(V;\, x. \operatorname{M}) \xrightarrow{\operatorname{op} V!W} M[W/x]\) } \end{prooftree}

    kjer se je vmes zgodila operacija \(\operatorname{op}\) s parametrom \(V\) in rezultatom \(W\).

Imamo težavo. Kakšna je teorija za učinek izjem? Spomnimo se, da smo imeli

\begin{gather*} \begin{bprooftree} \AxiomC{} \UnaryInfC{\(\Gamma \vdash \operatorname{raise} : A\) } \end{bprooftree} \quad \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \AxiomC{\(\Gamma \vdash N : A\)} \BinaryInfC{\(\Gamma \vdash \operatorname{try} M \operatorname{with} N : A\)} \end{bprooftree} \end{gather*}

Monada je bila \(TX = X + 1\). Poskusimo z \[ \Sigma = \operatorname{raise} : o, \operatorname{try} : 2 \] in enačbo \(\operatorname{try}(\operatorname{raise}(), y) = y\). Problem je, da se \(\operatorname{try}\) ne obnaša enako kot ostale operacije, ker imamo \[ \operatorname{let} x = \operatorname{try}(M_1, M_2) \operatorname{in} N \not\cong \operatorname{try}(\operatorname{let} x = M_1 \operatorname{in} N, \operatorname{let} x_2 = M_2 \operatorname{in} N \] recimo za \(M_1 = M_2 = \operatorname{ret} 0\) in \(N = \operatorname{let} x = \operatorname{print}(42)\) in \(\operatorname{raise}()\).

Toda, že prosti model za \(\Sigma = \left\{ \operatorname{raise} : _0 \right\}\) nam da monado za izjeme \[ FX = \left\{ [x] \mid x \in X \right\} \cup \left\{ [ \operatorname{raise}()] \right\} \cong X + 1 \] Torej ima \(\operatorname{try}\) drugačno vlogo. Če ni operacija, kaj je?

Imejmo izjeme \(E_1, \dots, E_n\) in prestreznik \[ \operatorname{try} M \operatorname{with} E_1 \rightarrow M_1 \mid \cdots \mid E_n \rightarrow M_n. \] Alg. teorija je \(\left\{ E_1 : 0, \dots, E_n : 0 \right\}\).

Prestreznik nam za vsako izjemo da nadomestno vrednost. Ni samo funkcija \(\left\{ E_i \right\} \rightarrow \) ampak ga lahko vidimo tudi kot model teorije. V splošnem je model \[ M, (\llbracket \operatorname{op} \rrbracket : M^n \rightarrow M)_{\operatorname{op} : n \in \Sigma}. \] skupaj z enačbami, za izjeme pa imamo \[ (M, (\llbracket E_i \rrbracket : \underline{M^0 \rightarrow M}_{\cong M}))_{i=1,\dots, n} \]

See also (Pretnar, Matija, 2015).

Vsak element prostega modela \(FX\) lahko interpretiramo v poljubnem drugem modelu na \(X\), recimo \[ [m(i(4), m(e(), 3))] \] lahko interpretiramo v \((\Z, +, -, 0)\) kot \(-4 + (0 + 3) = -1\). V splošnem je model lahko tudi nad drugo množico \(Y\), če imamo preslikavo \(X \rightarrow Y\). Na primer \(f : \Z \rightarrow \Q\), \(f(m) = \frac{1}{1 + m^2}\). S tem naša interpretacija postane \[ \frac{1}{f(4)} \cdot (1 \cdot f(3)) = 17 \cdot \left(1 \cdot \frac{1}{1 + 3^{2}}\right) = \frac{17}{10} \] Prosti model ima univerzalno lastnost. Za vsak \(f : X \rightarrow Y\) in model \(Y\) imamo enolično določen homomorfizem \(h : FX \rightarrow Y\), da velja

\[\begin{tikzcd} FX && Y \\ \\ X \arrow["h", dashed, from=1-1, to=1-3] \arrow[hook', from=3-1, to=1-1] \arrow["f"', from=3-1, to=1-3] \end{tikzcd}\] Še več, vsi homomorfizmi \(FX \rightarrow Y\) so porojeni na ta način. Za vsako teroijo \(\mathcal{T}\) imamo kategorijo \(\underline{\mathbf{Mod}}_{\mathcal{T}}\) njenih modelov in homomorfizmov med njimi.

Imamo pozabljivi funktor \(U : \underline{\mathbf{Mod}}_{\mathcal{T}} \rightarrow \mathbf{Set}\) in ta funktor ima levi adjunkt \(F : \mathbf{Set} \rightarrow \underline{\mathbf{Mod}}_{\mathcal{T}}\). Imamo adjunkcijo \(F \vdash U\). Kompozicija \(UF\) je prosta monada, s katero smo delali ves čas.

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A \)} \AxiomC{\((\Gamma \vdash M_i : A)_i\)} \BinaryInfC{\(\operatorname{try} \underbrace{M}_{F \llbracket A \rrbracket} \operatorname{with} \underbrace{\left\{ E_1 \rightarrow M_1, \dots, \right\} : A}_{\text{model teorije za izjeme na } F \llbracket A \rrbracket}\) } \end{bprooftree} \end{gather*}

Vse skupaj je interretacija \(F \llbracket A \rrbracket\) v modelu \(\left\{ E_1 \rightarrow M_1, \dots \right\} : A\). To je le poseben primer za identiteto. Pripeljimo še našo preslikavo \(f : FX \rightarrow Y\). Dobimo

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \AxiomC{\(\Gamma, x : A \vdash N : B\)} \AxiomC{\((\Gamma \vdash N_i : B)_i\)} \TrinaryInfC{\(\operatorname{try} M \operatorname{with} \left\{ \operatorname{return} x \rightarrow N, (E_i \rightarrow N_i)_i \right\} : B\)} \end{bprooftree} \end{gather*}

Teorija za izjeme je najenostavnejša algebrajska teorija za učinke. Kaj so modeli drugih teorij? V splošnem je to \[ (M, (\llbracket \operatorname{op} \rrbracket : M^n \rightarrow M)_{(\operatorname{op} : n) \in \Sigma}) \] z razširjenimi operacijami pa \[ (M, (\llbracket \operatorname{op} \rrbracket : \llbracket P \rrbracket \times M^{\llbracket A \rrbracket} \rightarrow M)_{(\operatorname{op} : P \rightarrow A) \in \Sigma}) \] Prestreznike posplošimo na obliko

\begin{gather*} \begin{bprooftree} \AxiomC{\(\Gamma \vdash M : A\)} \AxiomC{\(\Gamma, x : A \vdash N : B\)} \AxiomC{\((\Gamma, x : P_i, k : A_i \rightarrow B \vdash N_i : B .\, \operatorname{op}_i : P_i \rightarrow A_i)\)} \TrinaryInfC{\(\Gamma \vdash \operatorname{handle} M \operatorname{with} \left\{ \operatorname{return} x \rightarrow N, (\operatorname{op}_i \rightarrow N_i) \right\} : B\) } \end{bprooftree} \end{gather*}
Tags: lecture-notes