---
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)


```

