Gambit(2)

マウスピースを作った。別にボクサーを目指す訳でもないんだけど。歯軋り防止用のやつ。 これで夜も静かになるかな。でも、手入れが大変。入れ歯洗浄剤で洗ってくださいですって。 まだ、一本も失歯はないのに、一気に老人の気分だな。

なんでこの歳になってかと言うと、ちょいと旅行に行ってきたんだ。その時に女房に迷惑を かけない為。いびきの有効な防止手段ってあるのかな? 鼻つまみバージョンを試してみたんだ けど、余り効果が無かったみたいだ。スマソ > 女房。

混浴を求めて九州地区へ。期待したけど、そんなの無かった。残念! まあ、雲仙とか別府とかで期待する方が無理か。でも、別府の旅館に置いてあった冊子によると 混浴フォーラムが行われてたとか。学術、芸術的に注目を集めているんですかね? 風呂に入るの湯衣とか水着なんて、とっても不自然だもの。それとも、混浴は3回で慣れるそう だから、長逗留してってねって言う、旅館の願望が篭っているのでしょうか。

湯布院は、九州の軽井沢を目指して人気を集めたみたいなんで、混浴特区を作ったら、人気 大沸騰。別府の坊主地獄みたいに、ふつふつと人気が湧き出て、そのうちに盛大な人気で、 予約殺到。予約は2年先まで埋まっています、なんて景気の良い話になるに違いない。

ああ、思わず混浴書いちゃったけど、普通に(真面目に)長崎の平和記念像でお祈りも しましたよ。それから、くまもん君には会えなかったけど、熊本城、古事記に出て来る 高千穂で、歴史のお勉強もしましたよ。

阿蘇の外輪山を越えて草千里へ行く時、巨大な風力発電機の風車が何台も見えたぞ。 常時強風な地なんでしょうな。あんな山の中だと電気を下界に下ろすのも無駄。電気を 地産地消してるんでしょうかね。

仕上げは、肝試しと冷感溢れる(風がとっても強くて寒かった)、九重・夢の吊り橋を 渡ってきましたよ。ただ橋を渡って、戻ってくるだけの橋だけど、日本一の吊り橋って 事で、地元は大いに潤っているそうだ。アイデア勝負だなあ。

だから、絶対、混浴特区を作ってください。> どこかの勇気ある観光協会の方

ウブでもGambit

前回はOpenBSDインストール記念でGambitをpkgから入れてみた。でも、tar玉から入れて こそ愛着が沸こうと言うもんだ。この所ほこりを被って出番が無い、Ubuntuにでも入れてやるか。

何たって、ウブは昔の常識が通じないLinuxだから、何となく出番は無くて、ソース御取り寄せ しかしてなかったんだ。世間でも、新常識に追従しようと頑張っておられる方が居ましたよ。 今時のLinux(Ubuntu11)での起動シーケンス おいらのウブは12.04製のサーバー版だけど、通用するんだろうな。

話は戻って、OpenBSDのportsで取り寄せたtar玉を使いました。普通にやればいいんだろうとconfigure したら、最後に、

configure:
**************************************************************************
***                                                                    ***
*** The option "--enable-single-host" was not specified to the         ***
*** configure script.  The Gambit-C system will compile correctly but  ***
*** typically the executables will run considerably slower than when   ***
*** "--enable-single-host" is specified.  On the other hand the build  ***
*** with "--enable-single-host" is typically slower and requires lots  ***
*** of RAM memory (>= 1 GB).  If you are willing to wait for the       ***
*** longer build, try the configure option "--enable-single-host".     ***
***                                                                    ***
**************************************************************************

こんな脅しが入ってしょげる。最初に言わんかいと思ってREADMEを見たら、模範的作成手順が出てた。 最初にREADMEを読むのは、新旧共通の常識でしたよ。ははは、と笑って誤魔化そう。

ウブには、Xマネージャとして、lxdeが入っているんで、emacsでメニューが使える。ならば、Gambit を動かすに、機能豊富な Quack がよかろう。(tar玉には、gambit.elも付いてましたけどね)

emacs上で*.scmを読み込んでおき、C-c C-lでファイルをgsiにロードは出来るんだけど、 C-c C-kでコンパイルしようとすると、出来んと言われる。10秒考えて、gscを起動しとけば いいんだと気付く。我ながら情けない。

Gambit v4.6.6

> "/home/sakae/t/fib.o1"
> (load "/home/sakae/t/fib.o1")
(time (fib 40))
    1639 ms real time
    1628 ms cpu time (1608 user, 20 system)
    no collections
    no bytes allocated
    no minor faults
    no major faults

Process scheme finished
Gambit v4.6.6

> "/home/sakae/t/fib.o2"
> ,q

Process scheme finished

C-c C-kすると、作成されたファイル名が返ってくるので、その回りを(load)で囲ってあげれば、 コンパイル結果が確かめられる。コンパイルする旅に、ファイルのシリアル番号が上がって行くのね。

また、OpenBSDではエラーになってた

sakae@ubuntu:~/t$ gsc -exe fib.scm

も、無事に動いた。

sakae@ubuntu:~/t$ ls -l fib*
-rwxrwxr-x 1 sakae sakae 4087150 Dec 15 08:07 fib
-rwxrwxr-x 1 sakae sakae    7663 Dec 15 08:08 fib.o1
-rw-r--r-- 1 sakae sakae     225 Dec 15 08:05 fib.scm
sakae@ubuntu:~/t$ ldd fib
        linux-gate.so.1 =>  (0x00906000)
        libutil.so.1 => /lib/i386-linux-gnu/libutil.so.1 (0x008f3000)
        libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0x0077c000)
        libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0x00df2000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00110000)
        /lib/ld-linux.so.2 (0x00600000)

でも、OpenBSDと違って、出来上がった実行ファイルが肥大化してる。gambitの実行環境を抱え こんじゃっているんだな。(これだと、配るには便利だけど)

OpneBSDと何が違うんだ? configureの時に与える指示によって、性格の異なるものが出来るの だろう。portsのMakefileを覗いて、見よう見まねで性格を変えてみる。

Gambitの作り直し

作り直してみた。そしたら、libgambcgsc.so がねぇーぞとほざくようになった。新常識に則って 、/etc/ld.so.conf.d/gambit.conf に、/usr/local/Gambit-C/lib と書き、ldconfigしとく。 これで、

sakae@ubuntu:~$ gsc -v
v4.6.6 20120523144153 i686-pc-linux-gnu "./configure '--enable-single-host' '--enable-shared' '--disable-absolute-shared-libs'"

そして、

sakae@ubuntu:~/z$ ls -l fib*
-rwxrwxr-x 1 sakae sakae 8590 Dec 16 07:26 fib
-rwxrwxr-x 1 sakae sakae 7663 Dec 16 07:25 fib.o1
-rw-r--r-- 1 sakae sakae  225 Dec 15 08:05 fib.scm

と、なった。やれやれ、お疲れさん。(自分で言ってどうすると)そんじゃ、マニュアルと首っ引きで、 いろいろなオプションを試してみます。

まずは、OpenBSDで失敗してたやつ。

sakae@ubuntu:~/z$ gsc -verbose -exe fib.scm
Parsing:
  "declare"
  "declare"
  "declare"
  "declare"
  fib
  "expr"
  "expr"

Compiling:
  fib

Dumping:
  #<primitive | fib|>
  #<primitive fib>

Compilation finished.
gcc    -Wno-unused -Wno-write-strings -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fPIC -fno-common -mieee-fp   -D___SINGLE_HOST  -I"/usr/local/Gambit-C/include" -c -o "fib.o"  fib.c
gcc    -Wno-unused -Wno-write-strings -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fPIC -fno-common -mieee-fp   -D___SINGLE_HOST  -I"/usr/local/Gambit-C/include" -c -o "fib_.o"  fib_.c
gcc     -Wno-unused -Wno-write-strings -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fPIC -fno-common -mieee-fp   -rdynamic  -D___SINGLE_HOST  -I"/usr/local/Gambit-C/include"  -o "fib"   fib.o fib_.o "/usr/local/Gambit-C/lib/libgambc.so" -lutil -ldl -lm

うむ、最適化レベルが、-O1 とは、生ぬるいな。これは、gambc-cc の設定をいじっておこう。 次は、gvmと言うバーチャルマシン語だな。

sakae@ubuntu:~/z$ gsc -gvm fib.scm
sakae@ubuntu:~/z$ lv fib.gvm
   :
**** #<primitive fib> =
#line 6 "/home/sakae/z/fib.scm"
#1 0 entry-point 1 ()                       ; +0=# +1=n
#line 7
  if (##fx< +1 '2) jump 0 #11 else #6       ; +0=# +1=n
#line 10
#2 8 return-point                           ; -1=# -2=n -3 -4=. -5 -6 -7 -8 +1=.
#line 9
  +1 = (##fx+ -4 +1)                        ; -1=# -2=n -3 -4 -5 -6 -7 -8 +1=.
  +2 = +1                                   ; -1=# -2=n -3 -4 -5 -6 -7 -8 +2=.
#line 7
  +1 = -2                                   ; -1=# -2=n -3 -4 -5 -6 -7 -8 +1=n +2=.
  +0 = -1                                   ; -1 -2=n -3 -4 -5 -6 -7 -8 +0=# +1=n +2=.
  jump 0 #3                                 ; +0=# +1=n +2=.
#3 0                                        ; +0=# +1=n +2=.
#line 10
  +1 = (##fx- +1 '2)                        ; +0=# +1=. +2=.
#line 7
  if (##fx< +1 '2) jump 0 #10 else #4       ; +0=# +1=n +2=.
#4 0                                        ; +0=# +1=n +2=.
#line 9
  -1 = +0                                   ; -1=# +1=n +2=.
  -2 = +1                                   ; -1=# -2=n +1=n +2=.
  -3 = +2                                   ; -1=# -2=n -3=. +1=n +2=.
  +1 = (##fx- +1 '1)                        ; -1=# -2=n -3=. +1=. +2=.
  +0 = #12                                  ; -1=# -2=n -3=. +0=. +1=. +2=.
  -4 = .                                    ; -1=# -2=n -3=. -4 +0=. +1=. +2=.
  -5 = .                                    ; -1=# -2=n -3=. -4 -5 +0=. +1=. +2=.
  -6 = .                                    ; -1=# -2=n -3=. -4 -5 -6 +0=. +1=. +2=.
  -7 = .                                    ; -1=# -2=n -3=. -4 -5 -6 -7 +0=. +1=. +2=.
  -8 = .                                    ; -1=# -2=n -3=. -4 -5 -6 -7 -8 +0=. +1=. +2=.
   :

この部分なんだろうな。意味不。大体、下に掲げた所を変換してるんだろうけど。

  6 (define (fib n)
  7   (if (< n 2)
  8       n
  9       (+ (fib (- n 1))
 10          (fib (- n 2)))))

味方は、これかなあ?

In .gvm output, registers are prefixed by "+", stack by "-", objects by a single quote, labels by "#". Global variables are displayed by variable name, closed variables are enclosed in brackets, objects

サンプルを覗く

tar玉には付録が有って楽しい。バイナリーをただインストールして使うだけじゃ勿体ない。今回も 付録が付いていたよ。

sakae@ubuntu:~/gambc-v4_6_6/examples/pi$ ./pi 10000
(time (pi-brent-salamin 10 k))
    433 ms real time
    432 ms cpu time (352 user, 80 system)
    98 collections accounting for 44 ms real time (24 user, 24 system)
    31386376 bytes allocated
    1496 minor faults
    no major faults
31415926535897932384626433832795028841971693993751058209749445923078164062862089
  :
092764579310657922955249887275846101264836999892256959688159205600101655256375678

みんな大好きな10000のパイ。お望みとあらば幾らでも。。核な部分は以下の通り

(define (pi-brent-salamin-approximate base k) ; k is number of digits
    :
  (let ((one (number->fixed 1)))
    (let loop ((a one)
               (b (fixed.sqrt (quotient one 2)))
               (t (quotient one 4))
               (x 1))
      (if (= a b)
          (quotient (* a a) t)
          (let ((new-a (quotient (fixed.+ a b) 2)))
            (loop new-a
                  (integer-sqrt (* a b))
                  (fixed.- t (* x (fixed.square (fixed.- new-a a))))
                  (* 2 x)))))))

(define (pi-brent-salamin base k) ; k is number of digits
  (let ((n (ceiling (inexact->exact (+ 2 (log k))))))
    (quotient (pi-brent-salamin-approximate base (+ k n)) (expt base n))))

(define (main arg)
  (let ((k (string->number arg)))
    (pretty-print (time (pi-brent-salamin 10 k)))
    0))                                         

help and debug

マニュアル見てたらhelpが載ってた。

 > (help-browser "w3m")
 > (help pp)
 > ,(h call)

使うブラウザーを指定してhelp手続きを呼び出すだけ。調べたいキーワードを途中まで入力して 後はTABキーを押せば適当に補完してくれる。便利な機能なんだけど、使う前にhelp-browserの 呪文を唱えておかないといけないってのは、そんな不親切無いだろう。

そう思って調べてみたら、gambc-docにブラウザーの候補リストが載ってた。リストの先頭から ブラウザーを探して行って、最初に見つかったブラウザーを使ってくれる。おいらは、w3mを 指定しといたよ。正式には、configure --enable-help-browser=... とやるみたいだけど、 もう遅いよ。

debuggingの説明の中に、,? の細かい説明が出てたんで一読しとくといいかも。goshより 複雑で使いこなせるかなあ。まあ、簡単な所から。

> (load "fib.scm")
"/home/sakae/z/fib.scm"
> (pp fib)
(lambda (n) (if (< n 2) n (+ (fib (- n 1)) (fib (- n 2)))))
> (trace fib)
> (fib 2)
| > (fib 2)
| | > (fib 1)
| | 1
| | > (fib 0)
| | 0
| 1
1

次はステッパーだな。

> (step-level-set! 1)
> (begin (step) (fib 4))
*** STOPPED IN (console)@3.15
1> ,s
| > (fib 4)
*** STOPPED IN fib, "fib.scm"@7.7
1> ,s
| | > (< n 2)
| | #f
*** STOPPED IN fib, "fib.scm"@9.15
1> ,s
| | > (- n 1)
| | 3
*** STOPPED IN fib, "fib.scm"@9.10
1> ,s
| | > (fib (- n 1))
*** STOPPED IN fib, "fib.scm"@7.7
1> ,s
| | | > (< n 2)
| | | #f
*** STOPPED IN fib, "fib.scm"@9.15
1> ,c
| | 2
| 3
3

後、便利なものとしてbreakなんてのもあるぞ。

> (break fib)
> (fib 5)
*** STOPPED IN fib, "fib.scm"@7.8
1> ,c
*** STOPPED IN fib, "fib.scm"@7.8
1> ,c
*** STOPPED IN fib, "fib.scm"@7.8
1> ,c
*** STOPPED IN fib, "fib.scm"@7.8
1> ,b
0  fib                     "fib.scm"@7:8           <
1  fib                     "fib.scm"@9:10          (fib (- n 1))
2  fib                     "fib.scm"@9:10          (fib (- n 1))
3  fib                     "fib.scm"@9:10          (fib (- n 1))
4  (interaction)           (console)@20:1          (fib 5)
,e
n=2

Schemeでも充実したdebuggerを使えるなんて、有り難いな。

six

括弧がやたら多くて、取っ付き難いと言うあなたに朗報です。

sakae@ubuntu:~/z$ six
Gambit v4.6.6

> 1111111111111111111111111111 * 111111111111111111111111111;
123456790123456790123456789987654320987654320987654321

これ、bcの代わりになりますな。

> 2 + 5 * 3 + 4;
21
> (2 + 5) * (3 + 4);
49

そして、Schemeらしからぬ書き方も出来ます。

1> display("Hellow Gambit\n");
Hellow Gambit

だったら、Pythonでも使っとけってなりますが。。。 rubyは括弧を省略出来るんでなお良いってか? でも、C言語とみまがうばかりのスクリプトを書けますんで、邪険に扱わないでね。

[sakae@arch t]$ cat cp.six
#!/usr/local/Gambit-C/bin/six-script

void main (obj n_str)
{
  int n = \string->number(n_str);
  for (int i=1; i<=n; i++)
    \pretty-print(i);
}

実行は、当たり前に出来る。

[sakae@arch t]$ ./cp.six 3
1
2
3

反ってこんがらがるだけか?

iOSの方へ

contribに

This directory contains the following contributed softwares:

  GambitREPL    Gambit REPL app for iOS

こんなのも入ってて、MAC信者も安心!