OCamlでニュートン法(2)
さて、前回微分の計算をするところまでで終わっていたんだけど今回は実際に Newton-Raphson で実装してみよう。
(* small number *) let dx = 1.0e-10;; (* threshold *) let threshold = 1.0e-15;; (* derivative *) let deriv f x dx = (f (x +. dx) -. f x) /. dx;; (* X n+1 *) let xn_plus_one f x = x -. (f x) /. (deriv f x dx);; (* newton-raphson *) let newton_raphson f i = let rec newton x = let next_num = xn_plus_one f x in Printf.printf "%.20f\n" next_num; if abs_float (next_num -. x) < threshold then () else newton next_num in newton i;;
実行すると
# #use "newton.ml";; val dx : float = 1e-10 val threshold : float = 1e-15 val deriv : (float -> float) -> float -> float -> float = <fun> val xn_plus_one : (float -> float) -> float -> float = <fun> val newton_raphson : (float -> float) -> float -> unit = <fun> # let f x = x ** 2.0 -. 2.0;; val f : float -> float = <fun> # newton_raphson f 2.0;; 1.50000004137018194683 1.41666667356169995173 1.41421568647730544477 1.41421356237427708891 1.41421356237309514547 1.41421356237309492343 - : unit = () # newton_raphson f 10.0;; 5.10001781366008355434 2.74608272554679633259 1.73719668537143467901 1.44423846224395591165 1.41452565448231015743 1.41421359644891775353 1.41421356237308581960 1.41421356237309514547 1.41421356237309492343
このように2の平方根が求まるが、見ればわかるとおり二分法と比べて大幅に収束が速くなっている。ただし、誤差の関係上thresholdの値を1.0e-16以下にしてしまうと収束しなくなってしまうという問題もある。
OCamlでニュートン法(1) 微分の計算
さて、ニュートン法とは二分法のとこでもやったと軸との交点を求める場合に関数の接線を用いるという方法。
で、について解いて、
これを使う。
このうち、今回はの計算の仕方。
を求めるのに一番簡単なのは
においてを十分小さな値にして計算する方法。
差分法というらしい。
ということでを例に実際に試してみる。解析的手法だとであり、xが1の場合はとなる。では数値計算でも同様の結果となるか?
let f x = x ** 2.0;; let rec recderiv x dx t = if t < 500 then let deriv x dx = ( f ( x +. dx ) -. f x ) /. dx in Printf.printf "dx: %.17f dy/dx: %.17f error: %.17f\n" dx (deriv x dx) (abs_float (2.0 -. (deriv x dx))); recderiv x (dx /. 10.0) (t + 1) else () ;;
としてこれを deriv.ml というファイル名で保存。
で、実行。
# #use "deriv.ml";; val f : float -> float = <fun> val recderiv : float -> float -> int -> unit = <fun> # recderiv 1.0 1.0e-5 0;; dx: 0.00001000000000000 dy/dx: 2.00001000001392981 error: 0.00001000001392981 dx: 0.00000100000000000 dy/dx: 2.00000099992436686 error: 0.00000099992436686 dx: 0.00000010000000000 dy/dx: 2.00000010108780613 error: 0.00000010108780613 dx: 0.00000001000000000 dy/dx: 1.99999998784505761 error: 0.00000001215494239 dx: 0.00000000100000000 dy/dx: 2.00000016548074155 error: 0.00000016548074155 dx: 0.00000000010000000 dy/dx: 2.00000016548074155 error: 0.00000016548074155 dx: 0.00000000001000000 dy/dx: 2.00000016548074155 error: 0.00000016548074155 dx: 0.00000000000100000 dy/dx: 2.00017780116468158 error: 0.00017780116468158 dx: 0.00000000000010000 dy/dx: 1.99840144432528155 error: 0.00159855567471845 dx: 0.00000000000001000 dy/dx: 1.99840144432528155 error: 0.00159855567471845 dx: 0.00000000000000100 dy/dx: 2.22044604925031308 error: 0.22044604925031308 dx: 0.00000000000000010 dy/dx: 0.00000000000000000 error: 2.00000000000000000 dx: 0.00000000000000001 dy/dx: 0.00000000000000000 error: 2.00000000000000000 dx: 0.00000000000000000 dy/dx: 0.00000000000000000 error: 2.00000000000000000
結果を見るに dx が小さすぎると誤差が大きくなる傾向にある。これは打ち切り誤差や丸め誤差といった問題のためのようだ。次に任意精度を使って解いてみる。OCamlではNumというモジュールが相当するようなのでこのモジュールを使って試してみよう。
#load "nums.cma";; open Num;; let f x = x **/ Int 2;; let rec recnumderiv a b t = if t < 500 then let deriv x dx = ( f ( x +/ dx ) -/ f x ) // dx in let ans = deriv a b in Printf.printf "%s\n" (approx_num_fix 180 ans); recnumderiv a ( b // (Int 10 ) ) (t + 1) else () ;;
これをnumderiv.mlというファイル名として実行。
# #use "numderiv.ml";; val f : Num.num -> Num.num = <fun> val recnumderiv : Num.num -> Num.num -> int -> unit = <fun> # recnumderiv (Int 1) (Int 1 // Int (-5)) 0;;
結果は実行してもらえばわかるが見事に 2 に収束していく。
ただこの Num モジュール、任意精度を扱えるのはいいがすごく扱いにくいのだった。
Ocamlで二分法(2) 平方根を求める&二分法の汎用部品化
昨日に続いて二分法を使い、今度は平方根を求めてみる。
二分法を使う場合に
対象となる関数が連続関数であり、 かつ の場合、 となる根 が区間 に存在する
ということなので を求めるにあたり、 という式において を満たす が解となる。(ちなみにこの式がピンとくるまでに結構時間がかかったw)
このように となる点が解となるように関数を作るのが二分法のキモらしい
ちなみに、二分法における解の精度は ということである。
では2の平方根を求めるプログラムを実装してみよう。
type sign = Positive | Negative ;; let f x = x ** 2.0 -. 2.0 ;; let g x = if x >= 0.0 then Positive else Negative ;; let rec bis ( x1, x2, x3, x4 ) = if x3 >= x4 then (x1, x2, x3, x4) else let xm = ( x1 +. x2 ) /. 2.0 in if g ( f xm ) = g ( f x1 ) then bis ( xm, x2, x3 + 1, x4 ) else bis ( x1, xm, x3 + 1, x4 ) ;;
実行してみる。
# bis (1.0, 2.0, 0, 30);; - : float * float * int * int = (1.41421356145292521, 1.41421356238424778, 30, 30)
今回はサクッと行った!
さてお気づきの通り、前のと比べると関数 f の定義しか変わっていない。
なので次は高階関数を使って関数 f を引数に指定できるようにしてみよう。
type sign = Positive | Negative ;; let g x = if x >= 0.0 then Positive else Negative ;; let rec bis ( f, x1, x2, x3, x4 ) = if x3 >= x4 then (x1, x2, x3, x4) else let xm = ( x1 +. x2 ) /. 2.0 in if g ( f xm ) = g ( f x1 ) then bis ( xm, x2, x3 + 1, x4 ) else bis ( x1, xm, x3 + 1, x4 ) ;;
と、これだけ。
実際にテストしてみる。
# let f x = x ** 2.0 -. 3.0;; val f : float -> float = <fun> # bis (f, 1.0, 2.0, 0, 30);; - : float * float * int * int = (1.73205080721527338, 1.73205080814659595, 30, 30) # let f x = x ** 2.0 -. 4.0;; val f : float -> float = <fun> # bis (f, 1.0, 3.0, 0, 30);; - : float * float * int * int = (1.99999999813735485, 2., 30, 30)
できた。
これまでは試行回数を指定してきたわけだけど、次に最小誤差に到達したらその時点でプログラムを終了させるようにしてみる。ここで最小誤差は 1.0e-15 とする。
type sign = Positive | Negative ;; let min_f = 1.0e-15;; let g x = if x >= 0.0 then Positive else Negative ;; let rec bis ( f, x1, x2, x3 ) = let xm = ( x1 +. x2 ) /. 2.0 in if ( x2 -. x1) < min_f then (x1, x2, x3 + 1) else if g ( f xm ) = g ( f x1 ) then bis ( f, xm, x2, x3 + 1 ) else bis ( f, x1, xm, x3 + 1 ) ;;
さらにグラフを書けるように中点の変遷をテキストに出力するようにする。
type sign = Positive | Negative ;; let min_f = 1.0e-15;; let out_file = "out.txt";; let g x = if x >= 0.0 then Positive else Negative ;; let rec bis ( oc, f, x1, x2, x3 ) = let xm = ( x1 +. x2 ) /. 2.0 in Printf.fprintf oc "%.17f\n" xm; if ( x2 -. x1) < min_f then Printf.printf "x1: %.17f x2: %.17f xm: %.17f try: %d\n" x1 x2 xm ( x3 + 1 ) else if g ( f xm ) = g ( f x1 ) then bis ( oc, f, xm, x2, x3 + 1 ) else bis ( oc, f, x1, xm, x3 + 1 ) ;; let fbis ( f, x1, x2, x3 ) = let oc = open_out out_file in bis ( oc, f, x1, x2, x3 ); close_out oc; ;;
で、結果が
# let f x = cos ( x /. 2.0 );; val f : float -> float = <fun> # fbis ( f, 0.0, 6.0, 0);; x1: 3.14159265358979312 x2: 3.14159265358979356 xm: 3.14159265358979312 try: 54 - : unit = ()
out.txtにも中点の値が書きこまれている。ちなみにこのプログラムを書いている途中、またもや盛大にハマっていた。Printf.printf の行の最後にあるセミコロンの必要性の有無が未だにさっぱりわかっていないのだ。まだまだヘタレである。
で、Excelでグラフおこしながら思ったんだけど、収束が速いってどのくらいからを速いというのだろうか?
Ocaml で二分法
最近、Ocaml と数値計算をセットで勉強することにしている。
さてこの二分法とは、解を含む区間の中点を求める操作を繰り返すことによって方程式を解く求根アルゴリズムだそうな・・・。詳しくはWikipediaの二分法を参照のこと。
で、円周率を二分法で求める例、全然たいしたことないコードなんだけど Ocaml で書くのに一時間以上もかかってしまった。でも再帰関数が身に染み込んだ気がするので良し。
アルゴリズムとしてはが円周率になることを利用し、その近似値を二分法で求めるというもの。なのででも同様だと思う。
type sign = Positive | Negative ;; let f x = cos ( x /. 2.0 );; let g x = if x >= 0.0 then Positive else Negative ;; let rec bis ( x1, x2, x3, x4 ) = if x3 >= x4 then (x1, x2, x3, x4) else let xm = ( x1 +. x2 ) /. 2.0 in if g ( f xm ) = g ( f x1 ) then bis ( xm, x2, x3 + 1, x4 ) else bis ( x1, xm, x3 + 1, x4 ) ;;
実行してみる。
# bis (0.0, 6.0, 0, 50);; - : float * float * int * int = (3.14159265358978956, 3.14159265358979489, 50, 50)
収束するのに50回ちょっとかかるみたい。
文系であればこの二分法、意味は全く違う「二分法の罠」というほうが有名かもしれない。例えば
・クリスマスのプレゼントを子供に買ってあげなければいけない
・プレゼント代は自分の少ない小遣いから出さなければいけない
・なるべく出費を抑えたい
という場合において子供はPS3が欲しいものとしよう。
PS3は約3万円、でもできれば1万円以上節約したい。ここで親が繰り出すのが「二分法の罠」なのだ。親がクリスマス前あたりに子供に向かって
「Nintendo DSi と PSP Go だったらどっちをサンタさんに頼みたい?」
とあらかじめ聞いてしまう。
周りの子供達における DS の普及率が高ければ子供が DS を選ぶという期待値は予め高いものと予想できる。かつ DSi LL でも 18,000 円程度で1万円以上の節約になる。
ということでめでたくクリスマスに子供は DSi をゲットできて、親も PS3 を買わずに済んで見かけ上は win-win となる。
ここではセコい親の例をあげたけど、交渉が仕事のような人であれば知らず知らずのうちにもこの「二分法の罠」を使っていると思われる。キモは相手が許容できるギリギリのところにターゲットを合わせて「(こちら側に都合の良い)正解」となる選択肢を用意し、他の捨て駒となる選択肢もいくつか用意しておくこと。
ただし、将来的な展望を考えた上で使わないと仕事の依頼自体がなくなることもあるのは自明なので、できれば使わない方が良いのは当然である。
「プログラミングの基礎」
前回書いた通り、「最新コンパイラ構成技法」を読む途中で ML 習得の必要性を感じて OCaml を始めたわけだけど、今やすっかりハマっている。
「最新コンパイラ構成技法」については第二部をある程度読み終えて(いやこの二部は実際すごくイカしてる)、Ocaml をある程度使いこなせるようになったらまた第一部の続きから自分でもコンパイラの実装に挑戦しようと思っているところだ。
ということで、「プログラミングの基礎」という本を購入し、Ocaml の単純な記法とアルゴリズムの組み合わせの素晴らしさや難しさに一喜一憂しているのが現状。
ところでこの「プログラミングの基礎」という本はホントに非の付け所がないほど素晴らしい。プログラムを組む際の指針として必要なことはだいたいこの本から学べるんじゃないだろうか。
プログラミングの基礎 ((Computer Science Library))
- 作者: 浅井健一
- 出版社/メーカー: サイエンス社
- 発売日: 2007/03/01
- メディア: 単行本
- 購入: 17人 クリック: 409回
- この商品を含むブログ (127件) を見る
今まで必要性を感じずにすっ飛ばしてきたアルゴリズムという部分がこの本のテーマの一つ。一般企業向けのSIをやっていると高度なアルゴリズムが重要になる局面って少ないんだよね。もちろんBIなんかが絡んでくると途端にその重要性はアップするんだけど、どっちかというとデータを入力し、集計してどっかに出力するっていう単純なロジックを組み上げていくほうが多い。もちろん技術的に難しいところもあるけど、たいていは余裕をもってクリアできる範疇だったりする。だからSI企業の募集要項ではどの言語、どのDBを扱えるか、フレームワーク使ってWEBアプリ作れるかっていう程度しか指標にならない・・・。
でもホントはそういう、きっとどこかで誰かが全く同じものを作ってるんだろうなっていうような部分を超えて、新しい価値を生み出していくっていうのが重要なんじゃないか。例えば Google の検索技術みたいなね。確かに最初はアイデア勝負というのは認めるし、アイデアって実際ものすごく大切なんだけどそれが高度な技術の延長上にないのであればそれは実は資本勝負にすぎず、後発の資金力のある企業に飲み込まれてしまうだろう。
その高度な技術を伴った新しい価値を生み出す重要な基礎力の一つがコンピューターサイエンス。
コンピューターサイエンスとはプログラミングと様々な「学」が合流する部分にあると自分では捉えている。その「学」とプログラミングをくっつける糊の役割をしてくれるのが数学(これも学なわけだけど)で、だからこそ自分は数学を今必死にやっている。
数学を学んでいくためにはかなりの労力を要する。小説と違って数学の本を読んでいくのにはかなりの時間がかかって、たとえばたった半ページを理解するのに丸一日、もしくはそれ以上かかったりというのがザラだ。
たびたび、自分の頭の悪さに思いっきり辟易しながらもゆっくりとその歩を進めている途中である。
訳あってOCaml
まさか自分が OCaml を勉強するとは全くもって思っていなかったんだけど、訳あって只今 OCaml 勉強中。
というのも「最新コンパイラ構成技法」を読んでいて、その原著が「Modern Compiler Implementation in ML」。「Modern Compiler Implementation in C」でもないし、ましてや「Modern Compiler Implementation in Java」でもない。MLなの。ML。
で、その本の二章に ML-Lex という ML 向けの字句解析器が登場し、あーやっぱりML書けないとダメかと思うに至り、幸い Ubuntu なら ml-lex や ml-yacc、smlnj(Standard ML of New Jersey) のパッケージはあるんだけど、でもどうせならもっと実用的なのがいいなと思って OCaml に行き着いたと。いろいろ特殊に感じるところはあるけれど、独特な関数の書き方なんかもそんなに苦にならない。前に Erlang やったからかな。おかげでようやく関数型プログラミング言語像がイメージとして捉えられるようになってきたっぽい。
最新コンパイラ構成技法
- 作者: Andrew W. Appel,神林靖,滝本宗宏
- 出版社/メーカー: 翔泳社
- 発売日: 2009/10/30
- メディア: 大型本
- 購入: 6人 クリック: 165回
- この商品を含むブログ (26件) を見る
Modern Compiler Implement in ML
- 作者: Andrew W. Appel
- 出版社/メーカー: Cambridge University Press
- 発売日: 2008/08/21
- メディア: ペーパーバック
- 購入: 3人 クリック: 3回
- この商品を含むブログ (5件) を見る
Modern Compiler Implement in C
- 作者: Andrew W. Appel
- 出版社/メーカー: Cambridge University Press
- 発売日: 2008/08/21
- メディア: ペーパーバック
- 購入: 2人 クリック: 10回
- この商品を含むブログ (5件) を見る
Modern Compiler Implementation in Java
- 作者: Andrew W. Appel,Jens Palsberg
- 出版社/メーカー: Cambridge University Press
- 発売日: 2002/11
- メディア: ハードカバー
- クリック: 1回
- この商品を含むブログ (2件) を見る
それとは別に字句解析器と構文解析器の使い方を勉強。
Lex & Yacc や
Lex & Yacc (A Nutshell Handbook)
- 作者: John R. Levine,Tony Mason,Doug Brown
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 1992/10/01
- メディア: ペーパーバック
- 購入: 2人 クリック: 6回
- この商品を含むブログ (6件) を見る
flex & bison: Text Processing Tools
- 作者: John Levine
- 出版社/メーカー: O'Reilly Media
- 発売日: 2009/08/24
- メディア: ペーパーバック
- クリック: 7回
- この商品を含むブログ (1件) を見る
- 作者: Steven John Metsker
- 出版社/メーカー: Addison-Wesley Professional
- 発売日: 2001/03/26
- メディア: ペーパーバック
- クリック: 3回
- この商品を含むブログを見る
あとは Lua のレクサとパーサのソース読んでみたり。
前途多難だけど、こういういかにもCSっぽい勉強ってしたことがなかったのでそれなりに楽しめる。
Resources:
- The Caml Language
- http://caml.inria.fr/
- The Objective Caml system release 3.11 Documentation and user's manual
- http://caml.inria.fr/pub/docs/manual-ocaml/index.html
- Introduction to Object Caml
- http://files.metaprl.org/doc/ocaml-book.pdf
- Comparing Objective Caml and Starndard ML
- http://adam.chlipala.net/mlcomp/
- Standard ML and Objective Caml, Side by Side
- http://www.mpi-sws.org/~rossberg/sml-vs-ocaml.html
- Developing Applications With Objective Caml
- http://caml.inria.fr/pub/docs/oreilly-book/
- OCaml for Scientists
- http://www.ffconsultancy.com/products/ocaml_for_scientists/chapter1.html
- Using, Understanding, and Unraveling The OCaml Language From Practice to Theory and vice versa
- http://caml.inria.fr/pub/docs/u3-ocaml/index.html
- A Concise Introduction to Objective Caml
- http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html
- OCaml.jp
- http://ocaml.jp/
- OCaml プログラミング入門
- http://www.i.kyushu-u.ac.jp/~bannai/ocaml-intro/
- Objective Caml 入門
- http://www.sato.kuis.kyoto-u.ac.jp/~igarashi/class/isle4/mltext/ocaml.html
- OCamlチュートリアル
- http://www.ocaml-tutorial.org/ja
- お気楽 OCaml プログラミング入門
- http://www.geocities.jp/m_hiroi/func/ocaml.html
- 速攻MinCamlコンパイラ概説
- http://min-caml.sourceforge.net/
- 超特急:一時間でわかるML超入門
- http://min-caml.sourceforge.net/index2.html
autoconf 2.66 にハマる。というか使っちゃいけない。
事の発端は ruby の 1.9.2 を rc1 ではなくブランチリポジトリから直接持ってきて configure && make してインストールしようとしたら configure スクリプトがなかったので autoconf を走らせた時。
開発機が CentOS5 でデフォルトパッケージの Autoconf は 2.59、この状態で ruby のソースディレクトリにおいて autoconf を走らせるとバージョン 2.60 以上が必要というエラーメッセージが出たので GNU のサイトから autoconf の 2.66 をダウンロードしてインストール。で、autoconf実行。
$ autoconf configure.in:497: error: AC_CHECK_SIZEOF: requires literal arguments autoconf/types.m4:783: AC_CHECK_SIZEOF is expanded from... configure.in:489: RUBY_CHECK_SIZEOF is expanded from... configure.in:497: the top level autom4te: /usr/bin/m4 failed with exit status: 1
というエラーが発生してしまい、先に進めなくなってしまった。
autoconf のサイトに行ってみると m4 の 1.4.6 以降が最低限必要って書いてある。
$ m4 --version GNU M4 1.4.5 Written by Rene' Seindal. Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
このせいかなーと思って m4 もソースからインストールしなおし。
$ m4 --version m4 (GNU M4) 1.4.14 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
さらに autoconf ももう一回 configure &コンパイル&インストール。
もう大丈夫だろうと autoconf を再び走らせると
$ autoconf configure.in:497: error: AC_CHECK_SIZEOF: requires literal arguments ../../lib/autoconf/types.m4:765: AC_CHECK_SIZEOF is expanded from... configure.in:408: RUBY_CHECK_SIZEOF is expanded from... configure.in:497: the top level autom4te: /usr/local/bin/m4 failed with exit status: 1
またも同様な結果になってしまったのでググってみたらすぐに原因が見つかった・・・。
Don't try autoconf 2.66 at home just yet!
こちらに書かれていることを ruby の configure.in に当てはめて調べてみると、
RUBY_CHECK_SIZEOF(void*, [int long "long long"], [ILP LP LLP])
の部分で void* を渡していて RUBY_CHECK_SIZEOF 定義内の AC_CHECK_SIZEOF([$1], 0, [$4]) でコケてしまうって寸法。
結果的には autoconf 2.66 のリグレッションバグのようで、
http://osdir.com/ml/autoconf-gnu/2010-07/msg00007.html
こちらに修正パッチがあがってる。
これを適用した autoconf でようやく configure スクリプトの作成が可能になり、喜び勇んで configure スクリプトを走らせ、make。
でもそうは問屋が卸さない。
# make gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o main.o -c main.c gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o dln.o -c dln.c gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o dmydln.o -c dmydln.c gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o dmyencoding.o -c dmyencoding.c gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o version.o -c version.c gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/i686-linux -I./include -I. -DRUBY_EXPORT -o dmyversion.o -c dmyversion.c /usr/local/ruby_1_9_1/bin/ruby -I. ./tool/compile_prelude.rb ./prelude.rb miniprelude.c bison -d -o y.tab.c parse.y make: *** [parse.c] パイプが切断されました
ぐばー。
bisonよ、お前もか・・・。
# bison --version bison (GNU Bison) 2.3 Written by Robert Corbett and Richard Stallman. # rpm -e bison --nodeps
再び GNU のサイトから bison の 2.4.2 を引っ張ってきてインストール。
# bison --version bison (GNU Bison) 2.4.2 Written by Robert Corbett and Richard Stallman.
これでようやく make が通った。
# /usr/local/ruby_1_9_2/bin/ruby --version ruby 1.9.2dev (2010-07-06 revision 28549) [i686-linux]
ちなみに 1.9.2 の RC1 だったり、もしくは OS が新しめの ubuntu なんかであれば苦労レスで configure && make がするりと通る。
で、結論。
新しいものを試すって場合、CentOS5 の賞味期限はもう切れているってこと。RHEL6 がすでに beta2 に入り、それほど遠くない時期に正式版がリリースされることを考えると新規プロジェクト向けのサーバ構築で CentOS5 にこだわる理由はないし、そもそも何でそれ使うんだって話になるんだろう。ちなみに現在個人的に契約している VPS は CentOS5 なのだけれども、利用しているソフトウェアは殆どソースからコンパイルしたもので、パッケージは uninstall されゆく一方。ディストリビューションの恩恵を受けることがほぼ出来ない状態になってしまっている。
枯れたパッケージを乗っけて運用するのであれば CentOS5 でぜーんぜん問題ないんだけどなー。