[SML 7884] Re: 連想計算というリフレクティブな手法
Narita Takaoki
Narita.Takaoki @ exc.epson.co.jp
2010年 12月 17日 (金) 18:09:45 JST
成田です。
> 佐原です。
Smalltalk じゃない言語でズンズン行くのもなんですけれど、
> VDM++だと、高階関数使ってもリフレクション的なことはできそうもな
> いので、数値アルゴリズムで作りました :-)
こんなん書いてみました:
class Sequential_Square
functions
static public sequential_square :
((nat * nat) -> (nat * nat)) * nat1
+> ((nat * nat) -> (nat * nat))
sequential_square (T, n) ==
if (n = 1) then
T
else
if (n rem 2 = 1) then
(sequential_square(T, n - 1)) comp T
else
(sequential_square(T, floor(n / 2))) ** 2;
end Sequential_Square
class Fibonacci is subclass of Sequential_Square
functions
static public fibo : (nat * nat) +> (nat * nat)
fibo (pre_f) ==
mk_(pre_f.#1 + pre_f.#2, pre_f.#1);
static public fibonacci : nat1 +> nat
fibonacci (n) ==
if (n = 1) then
1
else
((sequential_square (fibo, n - 1))(mk_(1,0))).#1;
end Fibonacci
Sequential_Square が中途半端で気持ち悪いのですが、多相型関数の定義が
よくわからなくて型チェックではじかれたので、こんな感じになってしまいました。
高階関数を駆使して関数合成で問題を解く設計を書こうとすると、関数の型宣言
で死にそうになる気がする・・・ことに汎用性を持たせようとすると・・・
Haskell とかも死にそうになるけど、まだしも・・・
関数に対する comp と ** 演算子は便利。ぶっちゃけ、整数値が戻ってくる範
囲では sequential_square (T, n) == T ** n; で十分速い。
> リフレクション使うより速いので、シンボリック実行しているVDM++インタープリ
> タでも、fastFib(-1)からfastFib(100)まで
> 全部計算しても、一瞬で終わりますが、多倍長計算できないのでfastFib(92)=
> 7540113804746369024までしか計算できません。
環境の違いでしょうか?fibonacci(78) までしか計算できませんでした。それより
上もいけたですが、値が浮動小数点数。さらに fibonacci(10000) だと "1.#INF"
などと戻ってきているようです。とりあえず戻ってくることは、戻ってくる。
# 当方、VDM++VICE。
--
セイコーエプソン株式会社 機器ソフトウェア統括センター
成田 隆興 Tel. 0263-58-8464 (職場代表電話)
SML メーリングリストの案内