最小不動点定理をfactを用いて確認する
定理
fを連続関数D\to D
とする
あるa\in Dが存在して、以下の2つを満たす
f(a) =a
f(b)=bならば、a\sqsubseteq b
また、この最小不動点aは以下のように表せる
a = \sqcup\{f^n(\bot)\;|\;n\in\mathbb{N}\}
まず、この\Phi_\mathrm{fact}をHaskellで定義すると以下のようになる
hsphi :: (Int -> Int) -> Int -> Int
phi f x = if x == 0 then 1 else x * f(x - 1)
これが、上の定理のfの具体例になっている
以下のようにして、段階ごとの部分関数factを定義できる
hsfact0 x = undefined
fact1 x = phi undefined x
fact2 x = (phi . phi) undefiend x
fact3 x = (phi . phi . phi) undefined x
fact4 x = (phi . phi . phi . phi) undefined x
...
例えば、 fact4
の定義は以下のように書いているのと同じ
\mathrm{fact4}(x) = \Phi^4_\mathrm{fact}(\bot)(x)
使用感はこうなる
hsfact4 0 -- 1
fact4 1 -- 1
fact4 2 -- 2
fact4 3 -- 6
fact4 4 -- error
fact4 5 -- error
要は、 factn
関数は、 (n-1)!
までを求められる部分関数になる
これを無限に続けていけば以下のようになるが、これは書けないので
hsfactInf x (phi . ... . phi) undefined x
普通に再帰的に定義したfactで代用する
hsfactInf x = if x == 0 then 1 else x * factInf (x - 1)
a = \sqcup\{f^n(\bot)\;|\;n\in\mathbb{N}\}となることを確認したい
これは、A=\{\bot,f(\bot),f(f(\bot)),f(f(f(\bot))),\cdots\}という集合があった時に、
その上限\sqcup Aが、fの最小不動点に等しくなる
ということを言っている
またこの関数は単調なので、不動点はこの最小不動点1つのみである
不動点が複数ある関数もある
最小の不動点が、
上限であることが直観に反するポイントな感じがある

factの話でのAは、
A = {fact0, fact1, fact2, ... , factInf}
という集合のことである
これの上限は、もちろん factInf
である
ということは、定理的には、
factInf
が、 phi
の最小不動点である
ということを言っている
つまり以下が成り立つ
factInf == phi factInf
確認と言うには厳密性に欠けるが、実際
phi factInf
は任意の自然数 x
を引数にとって、 x!
を求められる
hsphi factInf 5 -- 120
phi factInf 10 -- 3628800
..
また、不動点コンビネータである
fix関数を用いることで最小不動点が得られる
今回の場合は、 factInf == fix phi
になる
hsfix phi 5 -- 120
fix phi 10 -- 3628800
..