All checks were successful
Build / build (push) Successful in 8m40s
169 lines
4.6 KiB
Markdown
169 lines
4.6 KiB
Markdown
---
|
||
date: 2024-11-23 08:05
|
||
---
|
||
|
||
#mimium
|
||
|
||
元々のLambda-mmmは実際に使われているmimiumでの中間表現と比べて以下のような差がある
|
||
|
||
- タプルなど構造化された型がない(実際にはVMの命令にワードサイズの情報を付加しているのでこれは結構重要)
|
||
- letで宣言された変数に対しては代入ができる(部分的に参照型が使われている)
|
||
- delayやfeedの項を終端の値として扱う意味論(コンパイル時の正規化作業)と、実際の評価に使われる意味論が混ざっている
|
||
|
||
## 型
|
||
|
||
$$
|
||
\begin{align}
|
||
\tau ::=
|
||
& \quad unit &\\
|
||
|&\quad R \quad &\\
|
||
|&\quad I_n \quad &n \in \mathbb{N} \\
|
||
|& \quad \tau * \tau \quad &\\
|
||
|&\quad \tau → \tau &\\
|
||
% |&\quad \langle \tau \rangle
|
||
\end{align}
|
||
$$
|
||
|
||
## 値
|
||
|
||
$$
|
||
\begin{align}
|
||
v ::=
|
||
&\quad unit & \\
|
||
|&\quad R & R \in \mathbb{R} \\
|
||
|&\quad v * v \quad &\\
|
||
|&\quad \lambda x.e \\
|
||
|&\quad delay(x,e_{time},v_{bound})\\
|
||
|&\quad feed\ x.e
|
||
\end{align}
|
||
$$
|
||
ディレイは定数や関数を入力としては受け取らない(常に変数を参照する)
|
||
|
||
## 項
|
||
|
||
$$
|
||
\begin{align}
|
||
e_p ::=
|
||
&\quad unit & \\
|
||
|&\quad R & R \in \mathbb{R} \\
|
||
|
||
e ::=
|
||
&\quad e_p & \\
|
||
|&\quad e,e & [tuple]\\
|
||
|&\quad x\quad &[var]\\
|
||
|&\quad \lambda x.e &[abs]\\
|
||
.|&\quad let\; x\; =\; e\; in\; e &[let]\\
|
||
|&\quad e\; e &[app]\\
|
||
|&\quad delay(e,e_{time},e_{bound}) &[delay]\\
|
||
|&\quad feed\; x.e &[feed]
|
||
\end{align}
|
||
$$
|
||
|
||
## 評価環境(正規化時)
|
||
|
||
$$
|
||
\begin{align}
|
||
E ::= &\; ()\\
|
||
&|\; E :: (x,v)
|
||
\end{align}
|
||
$$
|
||
|
||
## 正規化の操作的意味論
|
||
|
||
$$
|
||
\begin{gathered}
|
||
&\frac{E \vdash e_{bound} \Downarrow v_{bound} }
|
||
{E \vdash delay\; e\;e_{time}\; e_{bound} \Downarrow delay\; e \; e_{time}\; v_{bound} } &\textrm{[E-DELAY]} \\\\
|
||
|
||
&\frac{}{E^n \vdash\ \lambda x.e \Downarrow cls(\lambda x.e , E^n) }\ &\textrm{[E-LAM]} \\
|
||
|
||
&\frac{ E^{n-1} \vdash e \Downarrow v_1\ E^n, x \mapsto v_1 \vdash e \Downarrow v_2 }{E^n, x \mapsto v_2\ \vdash\ feed\ x\ e \Downarrow v_1}\ &\textrm{[E-FEED]} \\
|
||
|
||
&\frac{E^n \vdash e_c \Downarrow n \quad n > 0\ E^n \vdash e_t\ \Downarrow v\ }{E^n \vdash\ if (e_c)\ e_t\ else\ e_t \Downarrow v }\ &\textrm{[E-IFTRUE]}\\
|
||
&\frac{E^n \vdash e_c \Downarrow n \quad n \leqq0\ E^n \vdash e_e\ \Downarrow v\ }{E^n \vdash\ if (e_c)\ e_t\ else\ e_t \Downarrow v }\ &\textrm{[E-IFFALSE]}\\
|
||
&\frac{E^n \vdash e_1 \Downarrow cls(\lambda x_c.e_c, E^n_c) E^n \vdash e_2 \Downarrow v_2\ E^n_c,\ x_c \mapsto v_2 \vdash e_c \Downarrow v }{E^n \vdash\ e_1\ e_2 \Downarrow v }\ &\textrm{[E-APP]}
|
||
\end{gathered}
|
||
|
||
$$
|
||
|
||
## 実用スモールステップ意味論
|
||
|
||
アイデア:クロージャ呼び出しとそれ以外の関数呼び出し(グローバルに登録されたものと即時呼び出しされるものとか)を分けよう
|
||
|
||
OCamlでの疑似コード(未完成)
|
||
|
||
```Ocaml
|
||
type expr = NumLit of float
|
||
| Var of string
|
||
| App of expr * expr
|
||
| Lam of string * expr
|
||
| Delay of int * expr * expr
|
||
| Feed of string * expr
|
||
| Quote of expr
|
||
| Splice of expr
|
||
| Tuple of expr list
|
||
| Proj of expr * int
|
||
type bound = string * value
|
||
and env = bound list
|
||
and value = Real of float
|
||
| OpenFn of string * expr * int
|
||
| Closure of string * expr * env
|
||
| Code of expr
|
||
type state = float list
|
||
type stage = int
|
||
type stateptr = int
|
||
|
||
let lookup: string->env->value =
|
||
fun name env -> let finder = fun (n,v) -> n == name in
|
||
let (_n,v) = List.find finder env in
|
||
v
|
||
|
||
|
||
|
||
let rec contain_freevars: string -> expr -> env -> bool =
|
||
...
|
||
|
||
|
||
let states = ... in
|
||
let stateptr = 0 in
|
||
let rec eval : stage -> expr -> env -> value =
|
||
fun stage e env -> match e with
|
||
| Var(name) ->
|
||
lookup env name
|
||
| Lam(x,e) ->
|
||
if contains_freevar(e) then OpenFn(x,e,statesize e)
|
||
else Closure(x,e,env)
|
||
| App(ef,ea) ->
|
||
let va = eval stage ea env in
|
||
let vf = eval stage ef env in
|
||
match vf with
|
||
| OpenFn(x,e,size)-> let r = eval stage e ((x,va)::env) in
|
||
shift stateptr size;
|
||
r
|
||
| Closure(x,e,cenv) -> eval stage e ((x,va)::cenv)
|
||
| Delay(n,et,ev) ->
|
||
let v = eval stage ev env in
|
||
let vt = eval stage et env in
|
||
update_ringbuf state stateptr v vt
|
||
| Feed(x,e)->
|
||
let size = statesize e in
|
||
let last = getstate state stateptr in
|
||
let current = eval stage e ((x,last)::env)
|
||
state[stateptr] := current;
|
||
last
|
||
| Quote(e)->
|
||
rebuild stage+1 e env
|
||
| Splice(e)->
|
||
let v = rebuild stage-1 e env
|
||
match v with
|
||
| Code(e) -> eval e env
|
||
_-> raise
|
||
and rebuild : stage -> expr -> env =
|
||
fun stage e env ->
|
||
if stage == 0 then eval e env
|
||
else Code(e)
|
||
|
||
|
||
```
|
||
|